死锁
- 所谓死锁就是必须发生在下面的四个必要条件
- 资源互斥条件
- 保持与请求条件
- 不可剥夺条件
- 循环等待条件
- 简而言之就是访问的资源有互斥性, 也就是说是资源使不可抢占式或者是可消耗型资源
- 多个事务都已经占有资源, 并且想获取其他资源, 占有的资源有不可剥夺性, 想访问的资源被循坏等待
- 比如下面这个例子
建表
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的记录,此时该行记录已经加了排它锁,无法进行更新操作,需要等待锁释放
…
这两个事务相互等待对方的排它锁释放,如此出现了死锁