Mysql并发时经典常见的死锁原因及解决方法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Mysql并发时经典常见的死锁原因及解决方法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3256字,纯文字阅读大概需要5分钟。
内容图文
> select * from t3 where id in (8,9) for update; +----+--------+------+---------------------+ | id | course | name | ctime | +----+--------+------+---------------------+ | 8 | WA | f | 2016-03-02 11:36:30 | | 9 | JX | f | 2016-03-01 11:36:30 | +----+--------+------+---------------------+ rows in set (0.04 sec) Session2: select * from t3 where id in (10,8,5) for update; 锁等待中…… 其实这个时候id=10这条记录没有被锁住的,但id=5的记录已经被锁住了,锁的等待在id=8的这里。 不信请看 Session3: mysql> select * from t3 where id=5 for update; 锁等待中 Session4: mysql> select * from t3 where id=10 for update; +----+--------+------+---------------------+ | id | course | name | ctime | +----+--------+------+---------------------+ | 10 | JB | g | 2016-03-10 11:45:05 | +----+--------+------+---------------------+ row in set (0.00 sec) 在其它session中id=5是加不了锁的,但是id=10是可以加上锁的。案例2:
在开发中,经常会做这类的判断需求:根据字段值查询(有索引),如果不存在,则插入;否则更新。
以id为主键为例,目前还没有id=22的行 Session1: select * from t3 where id=22 for update; Empty set (0.00 sec) session2: select * from t3 where id=23 for update; Empty set (0.00 sec) Session1: insert into t3 values(22,‘ac‘,‘a‘,now()); 锁等待中…… Session2: insert into t3 values(23,‘bc‘,‘b‘,now()); ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
当对存在的行进行锁的时候(主键),mysql就只有行锁。
当对未存在的行进行锁的时候(即使条件为主键),mysql是会锁住一段范围(有gap锁)
锁住的范围为:
(无穷小或小于表中锁住id的最大值,无穷大或大于表中锁住id的最小值)
如:如果表中目前有已有的id为(11 , 12)
那么就锁住(12,无穷大)
如果表中目前已有的id为(11 , 30)
那么就锁住(11,30)
对于这种死锁的解决办法是:
insert into t3(xx,xx) on duplicate key update `xx`=‘XX‘;
用mysql特有的语法来解决此问题。因为insert语句对于主键来说,插入的行不管有没有存在,都会只有行锁。
案例3:
直接上情景:
mysql> select * from t3 where id=9 for update; +----+--------+------+---------------------+ | id | course | name | ctime | +----+--------+------+---------------------+ | 9 | JX | f | 2016-03-01 11:36:30 | +----+--------+------+---------------------+ row in set (0.00 sec) Session2: mysql> select * from t3 where id<20 for update; 锁等待中 Session1: mysql> insert into t3 values(7,‘ae‘,‘a‘,now()); ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
这个跟案例一其它是差不多的情况,只是session1不按常理出牌了,
Session2在等待Session1的id=9的锁,session2又持了1到8的锁(注意9到19的范围并没有被session2锁住),最后,session1在插入新行时又得等待session2,故死锁发生了。
这种一般是在业务需求中基本不会出现,因为你锁住了id=9,却又想插入id=7的行,这就有点跳了,当然肯定也有解决的方法,那就是重理业务需求,避免这样的写法。
转:https://www.cnblogs.com/zejin2008/p/5262751.html
附记,推荐两篇好文章
案例4:
http://hedengcheng.com/?p=844
MySQL 加锁处理分析:
http://hedengcheng.com/?p=771
Mysql并发时经典常见的死锁原因及解决方法
标签:业务 values 情况 根据 最大 避免 mysql 页面锁 页面
本文系统来源:http://www.cnblogs.com/fps2tao/p/7894547.html
内容总结
以上是互联网集市为您收集整理的Mysql并发时经典常见的死锁原因及解决方法全部内容,希望文章能够帮你解决Mysql并发时经典常见的死锁原因及解决方法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。