一篇文章里面有完整示例MySQL记录锁、间隙锁、临键锁小案例演示 。所以这里间隙锁写的都是左开右开的范围,可能临界点有点模糊,但不影响分析这个案例的死锁问题 。
2)通过事务A和事务B的update语句,我们可以发现其实它们都持有间隙锁(10,20)的这段范围,说明间隙锁范围是可以相互兼容的,意思就是只要你的10不在我(10,+∞)的间隙锁
范围内,就可以产生部分重合的间隙锁,也就是这里的(10,20) 。
五、实际开发中如何尽量避免死锁发生一般来讲在实际开发中,很少会发生死锁的情况,尤其是在业务量不是很大的情况下 。在并发很大的情况下可能会存在偶尔产生死锁 。
不过呢,在自己实际开发中,有遇到过请求一个接口出现100%概率死锁的情况 。
当时的场景其实很简单 。一段业务代码中,有去走Dubbo调其它接口服务,这就存在了两个事务,结果各自事务提交的时候,都需要等待对方的锁释放,就导致每次都发生死锁超时 。
这其实是一种代码不规范而导致死锁的发生 。这里也总结下如何尽量避免死锁发生 。
1)不同的应用访问同一组表时,应尽量约定以相同的顺序访问各组表 。对一个表而言,应尽量以固定的顺序存取表中的信息 。这点真的很重要,它可以明显的减少死锁的发生 。
举例:好比有a,b两张表,如果事务1先a后b,事务2先b后a,那就可能存在相互等待产生死锁 。那如果事务1和事务2都先a后b,那事务1先拿到a的锁,事务2再去拿a的锁,如果
锁冲突那就会等待事务1释放锁,那自然事务2就不会拿到b的锁,那就不会堵塞事务1拿到b的锁,这样就避免死锁了 。
2)在主键等值更新的时候,尽量先查询看数据库中有没有满足条件的数据,如果不存在就不用更新,存在才更新 。为什么要这么做呢,因为如果去更新一条数据库不存在的数据,
一样会产生间隙锁 。
举例:如果表中只有id=1和id=5的数据,那么如果你更新id=3的sql,因为这条记录表中不存在,那就会产生一个(1,5)的间隙锁,但其实这个锁就是多余的,因为你去更新一个
数据都不存在的数据没有任何意义 。
3)尽量使用主键更新数据,因为主键是唯一索引,在等值查询能查到数据的情况下只会产生行锁,不会产生间隙锁,这样产生死锁的概率就减少了 。当然如果是范围查询,
一样会产生间隙锁 。
4)避免长事务,小事务发送锁冲突的几率也小 。这点应该很好理解 。
5)在允许幻读和不可重复度的情况下,尽量使用RC的隔离级别,避免gap lock造成的死锁,因为产生死锁经常都跟间隙锁有关,间隙锁的存在本身也是在RR隔离级别来
解决幻读的一种措施 。
感谢这篇文章给自己提供了很好的思路,这篇文章也基本上按照这个思路往下写的
【手把手教你分析解决MySQL死锁问题】
推荐阅读
- 春季养生重点为护肝 肝火上升教你预防
- 手把手教你进行安卓逆向之篡改apk名称和图标
- 补血吃什么好 教你做六款家庭补血食疗方
- 专家教你三款药膳良方 让你与空调病说
- 松树特征介绍及生态特征分析
- 松树用途的介绍与分析
- Spring Cloud Stream使用详解及部分重点源码分析
- 三招教你查看别人在我电脑上操作了些什么,跟着我,看这个就够
- wireshark数据包分析工具
- 最全面的血型和性格分析
