美文网首页
delete+insert 引发的死锁问题

delete+insert 引发的死锁问题

作者: 卡萨布兰卡ginger | 来源:发表于2020-07-06 14:18 被阅读0次

问题

当上层业务会短时间内调用两次接口,导致线上报错死锁,报错信息如下:

屏幕快照 2020-07-06 上午10.56.05.png

死锁日志:


屏幕快照 2020-07-06 下午2.11.23.png

db结构

唯一索引 userid+userKey
普通索引 userkey+uservalue

场景还原

updateUniqueClientIdAndUserValue方法里面,一共有三个db操作:①根据userId和userKeys、userValues查询②根据userkey和value删除数据③批量保存或更新key-value信息

可直接定位到删除+insert这部操作的问题;

下面的表格是两个事务中的db操作:

(红色字体为db提示)

![ 屏幕快照 2020-07-06 下午2.14.12.png

]


屏幕快照 2020-07-06 下午2.14.12.png

至此,死锁问题复现

分析原因

首先,死锁为什么会产生?死锁的产生需要相互等待资源,相互等待的资源是什么?

了解这个之前,先了解一下delete操作的时候需要获取什么锁。

屏幕快照 2020-07-06 下午2.14.17.png

以及锁之间的兼容关系

屏幕快照 2020-07-06 下午2.14.22.png image.png

由此,可以分析出,结合死锁日志,事务1执行delete操作的时候,获取了索引区间(1086,415097555)的gap锁;

事务2执行的时候,也获取了索引区间(1086,415097555)的gap锁;由于gap锁之间相互兼容,到这一步为止是正常执行的;

事务1insert的时候,需要先获取一个插入意向锁(insert intention),由于官方文档解释,插入意向锁被认为是一种gap锁,这两个锁之间不兼容,事务1需要等待事务2释放索引区间(1086,415097555)的gap锁,此时db在等待事务2释放资源,也没有产生死锁;当事务2也执行insert的时候,事务2也需要获取插入意向锁,也要等待事务1释放索引区间(1086,415097555)的gap锁,事务2发生死锁,事务回滚,gap锁资源释放;事务1获取到这个锁,执行成功。

解决办法

可以看出来,主要是因为删除了一条不存在的数据导致的,再删除之前先查询,再删除;

我们可以来走一下先查询再删除的场景:

事务1删除一条数据,受影响1行,或者到了这条记录的锁以及这个索引之前的区间gap锁;事务2也要删除这条数据,需要先获得这条记录的行锁,等待事务1执行insert之后事务提交,释放锁资源;

思考

  1. 线上出现这个死锁的问题时,线下并没有马上复现,因为删除的数据是存在;只复现除了等待锁资源超时
  2. 死锁日志确实也提到了当insert操作时,获取的(1086,415097555)的插入意向锁那边有问题

相关文章

  • delete+insert 引发的死锁问题

    问题 当上层业务会短时间内调用两次接口,导致线上报错死锁,报错信息如下: 死锁日志: db结构 唯一索引 user...

  • Java多线程(下篇)

    一、死锁 1.同步锁 解决了线程安全问题,但会造成性能低下,还可能会引发一个问题(罕见):死锁 2.例子 a.一个...

  • 线程 6. 死锁

    没有办法解决,只能避免 java同步机制解决了线程安全问题,但是同时也引发了死锁现象。死锁现象如何解决呢: 没法解...

  • jstack命令:教你如何排查多线程问题

    这是之前的一个死锁案例: 一个多线程死锁案例,如何避免及解决死锁问题? 如程序中发生这样的死锁问题该如何排查呢?我...

  • 线程中的死锁

    死锁定义:若一组进程中的每一个进程都在等待仅由该组进程中的其它进程才能引发的事件,那么该组进程是死锁的 产生死锁的...

  • index_merge优化引发的死锁案例分析

    岁末年初,似乎是跟死锁杠上了。 从一次线上Mysql死锁引发的血案开始,到使用BeanUtils进行属性复制的坑,...

  • 1、mysql没有设置索引引发的死锁问题

    死锁日志 死锁日志 测试索引对于多事务的影响,也是并发的影响。 1、开启两个客户端工具,操作同一张表。t_noti...

  • Duplicate Key引发的死锁

    在依赖事务的项目中,如果SQL语句设计不合理或者执行顺序不合理,就容易引发死锁。本文介绍一个因为Duplicate...

  • replace into死锁引发的思考

    锁日志输出参考八怪大神 版本:Percona MySQL 5.7.22对于锁的学习我做了一些输出详细参考如下:ht...

  • 双重锁引发的死锁

    问题现象:我的一个系统级别的服务收不到亮灭屏广播了 刚开始怀疑广播没发出来,加了一些log之后发现广播是发出去了再...

网友评论

      本文标题:delete+insert 引发的死锁问题

      本文链接:https://www.haomeiwen.com/subject/ptbwqktx.html