INTRO
I built an e-commerce app with TypeScript and Sequelize ORM. In the app, I have a table that generates sequential invoice numbers based on the current day.
CREATE TABLE `dm_generate_trx` (
`id` int NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`increment_value` int NOT NULL DEFAULT '0',
`flag_hit` varchar(1) CHARACTER SET utf8 DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
This is how the table looks like:
|id |date |increment_value|flag_hit|created_at |updated_at |
|---|----------|---------------|--------|-------------------|-------------------|
|118|2022-05-19|1 |N |2022-05-19 10:10:21|2022-05-19 10:10:21|
|126|2022-05-19|2 |N |2022-05-19 10:10:54|2022-05-19 10:10:54|
|134|2022-05-19|3 |N |2022-05-19 10:11:37|2022-05-19 10:11:37|
|142|2022-05-20|1 |N |2022-05-20 08:12:14|2022-05-20 08:12:14|
|150|2022-05-20|2 |N |2022-05-20 08:12:34|2022-05-20 08:12:34|
In my TypeScript code, I have a query to generate the invoice number daily starting from 1 each day.
const count = await dm_generate_trx.count({
where: {
createdAt: {
[Op.gt]: todayStart, // will be "DATE NOW 00:00:00"
[Op.lt]: now,
},
},
transaction,
});
const currentCount = count + 1;
The SQL equivalent would be:
SELECT count(*) FROM dm_generate_trx
WHERE createdAt > 'DATE NOW 00:00:00' AND createdAt < 'DATE NOW HH:MM:SS'
I then add 1 to this count and insert it into the database.
ISSUE
The problem arises when multiple transactions run almost simultaneously, resulting in duplicates because the script doesn't capture the initially inserted value.
I expect the data to display as below:
id | date | increment_value | flag_hit | created_at | updated_at |
---|---|---|---|---|---|
118 | 2022-05-19 | 1 | N | 2022-05-19 10:10:21 | 2022-05-19 10:10:21 |
However, the actual data shows duplicates.
id | date | increment_value | flag_hit | created_at | updated_at |
---|---|---|---|---|---|
118 | 2022-05-19 | 1 | N | 2022-05-19 10:10:21 | 2022-05-19 10:10:21 |
How can I address this issue? I've tried using
ISOLATION_LEVELS.READ_UNCOMMITTED
without success. Should I resolve this at the code level or within the database?