mysql锁-记一次innodb死锁分析

本文详细分析了一次因并发导致的MySQL InnoDB死锁情况,通过实例展示了死锁的发生、回滚原因,并提供了相关日志及官方文档解释。通过前置条件和模拟测试,说明了死锁产生的原因在于并发事务对资源的锁顺序不同,导致循环等待。
摘要由CSDN通过智能技术生成

前言:
最近项目上压测出现了数据库死锁情况,经过一番排查,最终定位在updateData方法上

分析该方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public int udpateData(DataTrace trace){
	//根据索引更新数据,该子方法也加了@Transactional注解,使用默认事务机制:required
	updateOtherByIndex(trac);
	//根据主键更新数据
	updateOtherByPrimary(trac);
}

1.该方法执行了两个更新sql,一个根据索引,一个根据主键
2.外层调用udpateData方法,存在这种情况:首先异步调用,然后马上同步调用

分析死锁原因:

1.首先udpateData方法存在事务嵌套,子方法updateOtherByIndex使用默认事务机制required,会将已存在的事务加入当前事务中,所以两个更新sql是在一个事务中
2.既然没有开启一个新事务,则两个更新sql在一个事务中,并发调用udpateData方法就可能会出现问题(而且也是巧,第一个请求不会调用子方法updateOtherByIndex):
第一个进来事务会执行updateOtherByPrimary方法,获取主键锁
第二个进行事务会执行updateOtherByIndex方法,获取索引锁,然后执行updateOtherByPrimary方法,获取主键锁
这种循环情况下在压测环境很容易出现死锁了…

虽然原因找到了,不过为了更好地理解和加深学习,我本地做了一个死锁测试:
一、前置条件:

1.创建表:

CREATE TABLE `test_deadlock_table` (
  `primary_no` char(16) NOT NULL COMMENT '主键号',
  `index_no` char(16) NOT NULL COMMENT '索引号',
  `status` tinyint(4) unsigned NOT NULL COMMENT '状态',
  PRIMARY KEY (`primary_no`),
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值