mysql报错:Deadlock found when trying to get lock; try restarting transaction的解决方法

发布时间 - 2026-01-11 02:17:57    点击率:

发现问题

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

[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

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.

上面有两句:

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

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 opposite 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

总结

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


# mysql  # deadlock  # found  # 解决  # mysql死锁问题  # MySQL数据库事务transaction示例讲解教程  # mysql Non-Transactional Database Only(只支持MyISAM)  # MySQL数据库事务隔离级别介绍(Transaction Isolation Level)  # MySQL transaction事务安全示例讲解  # 死锁  # 的是  # 是在  # 两句  # 有什么  # 我就  # 出了  # 和我  # 都没  # 下了  # 等着  # 太大  # 而我  # 或者是  # 跑了  # 这篇文章  # 谢谢大家  # 要好好  # 或者其他  # 也不可能 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: nginx修改上传文件大小限制的方法  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  Python结构化数据采集_字段抽取解析【教程】  如何在景安云服务器上绑定域名并配置虚拟主机?  Laravel如何实现数据库事务?(DB Facade示例)  Laravel如何实现API版本控制_Laravel版本化API设计方案  高防服务器租用首荐平台,企业级优惠套餐快速部署  Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  JavaScript数据类型有哪些_如何准确判断一个变量的类型  网页设计与网站制作内容,怎样注册网站?  JS中对数组元素进行增删改移的方法总结  在线制作视频的网站有哪些,电脑如何制作视频短片?  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  微信小程序 五星评分(包括半颗星评分)实例代码  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  香港服务器网站卡顿?如何解决网络延迟与负载问题?  JavaScript如何操作视频_媒体API怎么控制播放  米侠浏览器网页背景异常怎么办 米侠显示修复  如何在阿里云ECS服务器部署织梦CMS网站?  高端网站建设与定制开发一站式解决方案 中企动力  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  微信小程序 配置文件详细介绍  如何确保西部建站助手FTP传输的安全性?  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  如何在万网ECS上快速搭建专属网站?  如何在IIS中配置站点IP、端口及主机头?  js代码实现下拉菜单【推荐】  如何在Windows服务器上快速搭建网站?  php json中文编码为null的解决办法  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  Laravel集合Collection怎么用_Laravel集合常用函数详解  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Laravel如何使用Collections进行数据处理?(实用方法示例)  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】