Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 避免在插入手动递增的收据编号时发生冲突_Php_Mysql_Sql_Deadlock_Database Deadlocks - Fatal编程技术网

Php 避免在插入手动递增的收据编号时发生冲突

Php 避免在插入手动递增的收据编号时发生冲突,php,mysql,sql,deadlock,database-deadlocks,Php,Mysql,Sql,Deadlock,Database Deadlocks,我有一个查询,每次用户购买时,都会从收据表中获取当前最高的收据\u计数器编号,以便创建新收据收据计数器在表中不唯一,因为它每年重置 receipt\u counter只是一个整数,用于生成类似于“pos\u id”-“receipt\u counter”的receipt\u标签 人们有可能在同一销售点同时购买产品(pos\u id) 获取新的收据\u计数器的函数如下所示: SELECT (MAX(receipt_counter) + 1) as next_receipt_counter FROM

我有一个查询,每次用户购买时,都会从
收据
表中获取当前最高的
收据\u计数器
编号,以便创建新收据<代码>收据计数器在表中不唯一,因为它每年重置

receipt\u counter
只是一个整数,用于生成类似于
“pos\u id”-“receipt\u counter”
receipt\u标签
人们有可能在同一销售点同时购买产品(
pos\u id

获取新的
收据\u计数器的函数如下所示:

SELECT (MAX(receipt_counter) + 1) as next_receipt_counter FROM receipts
问题是,当多人同时购买产品时,会触发生成新收据(以及收据编号),有时会发生冲突(多人获得相同的收据编号),因为检索收据计数器和将新收据插入数据库之间存在延迟

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


编辑:收据计数器需要是一个无间隙的序列号。

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

收货计数器是否需要是一个不断增加的数字且没有间隙

如果一个有间隙的大数字可以增加,那么在当前日期/时间之外生成一个数字怎么样?如果下降到毫秒或纳秒,发生碰撞的可能性很低

例如:

2013-11-13 13:08:15.012
->
1113130815012

(我省略了年份,因为你说数字每年都会重置)

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

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


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

您不能使用序列生成
收据\u计数器吗
?如果延迟很小,可以使用锁表。然后其他用户脚本将等待您解锁该表,即订单将写入数据库。不要尝试自己实现序列生成器,让数据库来实现。请参阅Lolo:s的答案。它需要一个无间隙的递增数字。这解决了我的冲突问题,但另一个问题是,当其中一个同步事务失败时,它将在我的
收据\u计数器中留下一个“间隙”