我有一个用户表,每个用户都会生成一个交易参考号,每次更新1次以获取下一个要使用的交易参考号。
该表与此类似:
UserName varchar(50), counter int
例如用户名:John的计数器编号为1 如果他选择参考编号,他的计数器编号将更新为2 所以他下次会用2作为参考编号。
问题在于因为许多用户使用此表。结果我得到了许多交易。可以任何人请指教。 THX
答案 0 :(得分:0)
建议为COUNTER列创建一个包含AUTO_INCREMENT
的新表,并插入任何想要获得新COUNTER的人。 AUTO_INCREMENT
负责为新行分配新的递增号码,您可以从正常select
查询中获取分配给任何特定人员的最新号码。
答案 1 :(得分:0)
简短回答:你无法阻止死锁。
为什么呢?仅仅因为您的系统设计如何工作。我会引用:
我有一个用户表,每个用户都会生成一个事务 每次获取下一笔交易时,参考编号和更新1 要使用的参考号
假设您只有2个用户。每个用户同时发出查询。现在,会发生的是每个用户使用数据快照进行操作。因此,他们两个都会计算,例如,下一个交易号将是2
。
因此,处理连接的两个线程将争夺锁定并最终陷入死锁。为了解决这个问题,MySQL杀了一个线程,让对方完成。他们为什么要争夺锁?他们正在查找相同的表/计数器/它是什么,为了获得正确的信息,任何人或任何东西都不能自由修改该信息。您很可能不希望为每个人(实际上是线程)获取相同的事务编号,因此MySQL在执行计数器增量时会对表进行锁定。
问题的根源在于,您正在尝试获取下一个事务数量,并且多个人(实际上是线程)最终查找相同的源以获取该数字。
这里没有太多选项,这里是:
通过重新发布交易来处理死锁。这就是它的完成方式。死锁不是你应该害怕的,它只是数据库告诉你保持数据完整性的方式,它拒绝一个线程来完成它的工作。
重新设计您的系统,这样您就不会依赖下一个交易号码。那部分可能更难,我们不知道什么依赖于这个功能,但是 - 这将是你最好的选择。我不知道是否可能,所以如果您不依赖下一个交易号,我建议您考虑如何使您的系统正常工作。