MySql~面试题目之写一个InnoDB引擎下事务死锁的例子

死锁

  • 所谓死锁就是必须发生在下面的四个必要条件
  1. 资源互斥条件
  2. 保持与请求条件
  3. 不可剥夺条件
  4. 循环等待条件
  • 简而言之就是访问的资源有互斥性, 也就是说是资源使不可抢占式或者是可消耗型资源
  • 多个事务都已经占有资源, 并且想获取其他资源, 占有的资源有不可剥夺性, 想访问的资源被循坏等待
  • 比如下面这个例子

建表

CREATE TABLE `test1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
  • id为主键索引

客户端一

--T1时刻
BEGIN;
 
--行级锁 id=1 的记录
select * from test1 where id=1 for update ;
 
--T3时刻
--更新 id=2 的记录
update test1 set id=5 where id=2;

客户端二

--T2时刻
BEGIN;
 
--行级锁 id=2 的记录
select * from test1 where id=2 for update ;
 
--T4时刻
--更新 id=1 的记录
update test1 set id=6 where id=1;
  • 运行结果
update test1 set id=5 where id=1
> 1213 - Deadlock found when trying to get lock; try restarting transaction
> 时间: 0.002s

分析

终端一在T1时刻 test1 表的id=1的记录加了排它锁

终端二在T2时刻 test1 表的id=2的记录加了排它锁

终端一在T3时刻要去更新test1表中id=2的记录,此时该行记录已经加了排它锁,无法进行更新操作,需要等待锁释放

终端二在T4时刻要去更新test1表中id=1的记录,此时该行记录已经加了排它锁,无法进行更新操作,需要等待锁释放

这两个事务相互等待对方的排它锁释放,如此出现了死锁

猜你喜欢

转载自blog.csdn.net/Shangxingya/article/details/113774808