插入手动增加的收据号码时避免碰撞

时间:2013-11-13 13:08:16

标签: php mysql sql deadlock database-deadlocks

我有一个查询,即每次用户购买都会从receipt_counter表中获取当前最高receipts个号码,以便创建新收据。 receipt_counter在表中并不是唯一的,因为它每年都会重置。

receipt_counter只是一个整数,用于生成receipt_label "pos_id"-"receipt_counter"。{ 人们有可能在同一销售点同时购买产品(pos_id)。

获得新receipt_counter的函数如下所示:

SELECT (MAX(receipt_counter) + 1) as next_receipt_counter FROM receipts

问题是当多人同时购买产品时,触发产生新收据(连同收据号码),有时会发生冲突(多人获得相同的收据号码),因为在检索收据计数器和插入之间存在一些延迟新收据进入DB。

有最佳方法来处理这类问题吗?我是否需要使用某种僵局,或者我最初的想法是否存在缺陷?我需要改变策略以便一起生成收据计数器?

编辑:receipt_counter需要是一个没有间隙的序号。

3 个答案:

答案 0 :(得分:1)

您可以仅为id创建单独的表,并在该id列上启用auto_increment。然后在2个步骤中添加收据 - 首先将新记录添加到id表,以接收返回生成的id。然后使用收到的ID添加实际收据。然后当你想要重置增量计数器时,你需要截断带有id的表。

答案 1 :(得分:1)

  

检索收据计数器和在DB中插入新收据之间存在一些延迟

您可以更改软件,以便在不创建实际收据的情况下代替或检索ID,它会创建收据(具有“待处理”状态或类似内容),然后检索其ID。在您当前创建收据的那一刻,您只需将其状态设置为“活动”或其他内容。

这样做可以摆脱获取和ID以及存储记录之间的时间差距,这在我看来是您问题的主要来源。

答案 2 :(得分:0)

receipt_counter是否需要增加数字无间隙

如果增加大量差距是可以的,那么如何在当前日期/时间之外生成一个数字呢?如果你下降到几毫秒或几纳秒,碰撞的可能性就会很低。

例如:

2013-11-13 13:08:15.012 - > 1113130815012
(我省略了年份,因为你说这个数字每年都会被重置)