1

我有一个查询,每次用户购买时都会receipt_counterreceipts表中获取当前最高的数字,以便创建新的收据。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

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

是否有处理此类问题的最佳实践?我是否需要使用某种死锁,还是我最初的想法有缺陷,我需要改变策略来一起生成收据计数器?

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

4

3 回答 3

1

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

于 2013-11-13T13:16:21.957 回答
1

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

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

这样做可以消除获取 ID 和存储记录之间的时间间隔,在我看来,这是问题的主要来源。

于 2013-11-13T13:30:05.453 回答
0

是否receipt_counter需要不断增加数量而没有差距

如果增加有间隙的数字是可以的,那么从当前日期/时间生成一个数字怎么样?如果你下降到毫秒或纳秒,那么发生碰撞的机会就非常低了。

例如:

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

于 2013-11-13T13:19:46.693 回答