In a given table, I have to fields: pos (point of sale) and voucher_number.
Both of them are grouped in a unique index
I need to have an unique sequence per pos, for example
ID | date | pos | voucher_number |
---|---|---|---|
1 | 2021-01-01 11:45:37 | 1 | 1 |
2 | 2021-01-01 17:22:45 | 1 | 2 |
3 | 2021-01-02 15:08:02 | 2 | 1 |
4 | 2021-01-02 15:08:02 | 1 | 3 |
5 | 2021-01-03 10:37:24 | 2 | 2 |
6 | 2021-01-03 10:37:24 | 3 | 1 |
7 | 2021-01-03 10:37:24 | 1 | 4 |
Different users can create different vouchers at the same time, so my concern is how to ensure that the sequence keeps it's natural order and doesn't repeat or skip numbers
The code that I'm working on is wrapped inside a transation and I was thinking of doing somethig like this (pseudo):
//At this point a transaction has already been started
function save_voucher($voucher_data)
{
//Notice the SELECT ... FOR UPDATE
$max_voucher_number = select max(voucher_number) as max_voucher_number from vouchers where pos = $voucher_data["pos"] for update;
$voucher_data["voucher_number"] = $max_voucher_number + 1;
//I can't alter save_voucher() in parent class
//But inside it would perform something like:
//insert into (pos, voucher_number) values ($voucher_data["pos"], $voucher_data["voucher_number"]);
return parent::save_voucher($voucher_data);
}
//After the method execution, a commit or rollback happens;
Or even something like:
//At this point a transaction has already been started
function save_voucher()
{
//I can't alter save_voucher() in parent class
$new_voucher_id = parent::save_voucher();
//Now, after a voucher had been created I could get the max sequence
//Notice the SELECT ... FOR UPDATE
$max_voucher_number = select max(voucher_number) as max_voucher_number from vouchers where pos = $pos for update;
//Then, I could update that voucher
update vouchers set voucher_number = $max_voucher_number + 1 where id = $new_voucher_id;
return $new_voucher_id;
}
//After the method execution, a commit or rollback happens;
Would the above guarantee that I will have a unique sequence per pos? Would a possible concurrency will affect the sequence in any way?
I'm using MySQL with all tables using InnoDB