我知道,当sql查询试图锁定已经锁定的行时,就会发生死锁,而我目前遇到了死锁。下面是我的sql查询:
INSERT INTO transactions (product_id, category, C, amount, date) SELECT 'SomeProduct', 'SomeCategory', v.username, 10, '2016-3-31' FROM balance v WHERE v.username = 'SomeUsername' AND v.balance + 10 >= 0
balance是一个虚拟表,用于对交易进行求和以获得用户余额。
当有相当数量的用户时,这个错误通常会被注意到,这使得测试变得困难,任何关于如何避免死锁的提示或任何可能的解决方案,因为我正在以非常多的方式将行插入transaction表中,并希望解决它!
我也尝试过捕捉异常,但我不能创建一个循环来重做查询,直到它完成。
发布于 2016-04-01 05:03:14
一般答案
只有当您有两个或更多资源、两个或更多进程,并且这些进程以不同的顺序锁定资源时,才会发生死锁。
假设进程1想要锁定资源A,然后是B,然后是C。进程2想要锁定B,然后是A,然后是C。
这可能会导致死锁,如果1得到A,然后2得到B,然后1等待B,2无限期地等待A。
谢天谢地,解决方案非常简单:任何时候,如果一个进程需要锁定两个或更多资源,它必须以“排序”的方式进行锁定。在本例中,如果进程2也获得A,然后是B,然后是C,则永远不会发生死锁。
具体答案
在您的情况下,您似乎以或多或少的随机顺序锁定了一个事务中的不同表行。尝试找出如何使用mysql释放锁,并确保您只持有实际需要的锁。如果您需要同时保存多个请求,请尝试以某种方式对您的请求进行排序。
如果不对你的代码有更多的了解就很难断定...谷歌对"mysql deadlock“的第一次点击显示了一些有希望的东西:https://www.percona.com/blog/2014/10/28/how-to-deal-with-mysql-deadlocks
https://stackoverflow.com/questions/36343488
复制相似问题