mysql报错:Deadlock found when trying to get lock;

发现问题

最近在补以前数据的时候程序突然报如下错误:

1

2

3

4

5

[2017-02-10 13:12:06.678] [INFO] mysqlLog - update tbl_playerdata_error: { [Error: ER_LOCK_DEADLOCK: Deadlock found when trying to get lock; try restarting transaction]

 code: 'ER_LOCK_DEADLOCK',

 errno: 1213,

 sqlState: '40001',

 index: 0 }

一看就是mysql出现了死锁问题,其实上面跑的程序在测试服跑了好久都没什么问题,为什么在正式服上会出现mysql的死锁问题呢,第一反应是不是数据量太大(3百多万条),可是也不可能啊,再说死锁和这些有什么鸡毛的关系,看来要好好解决下了。

问题分析

我的分析是:由于现在处理的是正式服的数据,而正式服还有许多用户在操作,应该是在用户查询,或者是其他操作的时候,和我这边的数据更新产生了死锁(首先说明使用的是:InnoDB存储引擎。由于用户那边的查询或者其他操作锁定了我需要的资源,而我这边更新也锁定了用户操作的一部分资源,两边都等着对方释放资源,从而导致死锁)。

解决方法

知道错误code之后,先来查看mysql的说明,关于上面的 Error: 1213 SQLSTATE: 40001,参见:Server Error Codes and Messages

1

2

3

Message: Deadlock found when trying to get lock; try restarting transaction

 

InnoDB reports this error when a transaction encounters a deadlock and is automatically rolled back so that your application can take corrective action. To recover from this error, run all the operations in this transaction again. A deadlock occurs when requests for locks arrive in inconsistent order between transactions. The transaction that was rolled back released all its locks, and the other transaction can now get all the locks it requested. Thus, when you re-run the transaction that was rolled back, it might have to wait for other transactions to complete, but typically the deadlock does not recur. If you encounter frequent deadlocks, make the sequence of locking operations (LOCK TABLES, SELECT ... FOR UPDATE, and so on) consistent between the different transactions or applications that experience the issue. See Section 14.8.5, “Deadlocks in InnoDB” for details.

上面有两句:

1

To recover from this error, run all the operations in this transaction again<br><br>If you encounter frequent deadlocks, make the sequence of locking operations (<code class="literal">LOCK TABLES</code>, <code class="literal">SELECT ... FOR UPDATE</code>, and so on) <br>consistent between the different transactions or applications that experience the issue

这两句也就道出了处理死锁的方法了,我就是在死锁错误发生的时候,使用定时器再重新做一次更新操作,这样就避免了上面出现的问题。

另外,参考了stack overflow上面一个回答:http://stackoverflow.com/questions/2332768/how-to-avoid-mysql-deadlock-found-when-trying-to-get-lock-try-restarting-trans

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

One easy trick that can help with most deadlocks is sorting the operations in a specific order.

 

You get a deadlock when two transactions are trying to lock two locks at <a href="https://www.xiaojishu.com/tags/oppo.html" target="_blank" class="infotextkey">OPPO</a>site orders, ie:

 

connection 1: locks key(1), locks key(2);

connection 2: locks key(2), locks key(1);

If both run at the same time, connection 1 will lock key(1), connection 2 will lock key(2) and each connection will wait for the other to release the key -> deadlock.

 

Now, if you changed your queries such that the connections would lock the keys at the same order, ie:

 

connection 1: locks key(1), locks key(2);

connection 2: locks key(1), locks key(2);

it will be impossible to get a deadlock.

 

So this is what I suggest:

 

Make sure you have no other queries that lock access more than one key at a time except for the delete statement. if you do (and I suspect you do), order their WHERE in (k1,k2,..kn) in ascending order.

Fix your delete statement to work in ascending order:

Change

 

DELETE FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND

To

 

DELETE FROM onlineusers WHERE id IN (SELECT id FROM onlineusers

 WHERE datetime <= now() - INTERVAL 900 SECOND order by id) u;

Another thing to keep in mind is that mysql documentation suggest that in case of a deadlock the client should retry automatically. you can add this logic to your client code. (Say, 3 retries on this particular error before giving up).

参考:http://blog.sina.com.cn/s/blog_4acbd39c01014gsq.html

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对小技术网的支持。

来源:https://www.xiaojishu.com/db/mysql/15105.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当在Java中调用MySQL函数时遇到"Deadlock found when trying to get lock; try restarting transaction"的报错,这通常表示在执行事务时发生了死锁。死锁是指两个或多个事务互相等待对方释放资源而无法继续执行的情况。 要解决这个问题,可以采取以下几种方法: 1. 重试事务:根据报错信息中的提示,可以尝试重新启动事务。在Java代码中,可以使用try-catch块来捕获该异常,然后在catch块中重新执行相同的事务操作。 2. 优化事务:死锁通常发生在多个事务同时访问相同资源时,可以通过优化事务的并发性来减少死锁的发生。例如,可以尽量减少事务的持续时间,避免长时间占用资源。 3. 加锁顺序:如果多个事务需要同时获取多个资源,可以约定一个固定的加锁顺序,以避免死锁的发生。可以根据业务需求和资源访问的频率来确定合适的加锁顺序。 4. 减少事务并发:如果死锁频繁发生,可以考虑减少事务的并发性,限制同时执行的事务数量。可以根据实际情况对并发控制进行调整,例如通过调整连接池的配置参数或调整数据库的并发控制参数。 总的来说,当在Java调用MySQL函数时遇到"Deadlock found when trying to get lock; try restarting transaction"的报错,需要注意死锁的发生原因,并采取相应的解决方法,如重试事务、优化事务、加锁顺序或减少事务并发等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MySql报错Deadlock found when trying to get lock; try restarting transaction 的问题解决](https://blog.csdn.net/X_Z_P/article/details/115872579)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [mysql报错Deadlock found when trying to get lock; try restarting transaction的解决方法](https://download.csdn.net/download/weixin_38595528/12826933)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [mysql中update时出现时报错Deadlock found when trying to get lock; try restarting transaction的原因...](https://blog.csdn.net/qq_42303467/article/details/118673187)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值