赞
踩
CREATE TABLE `t1_deadlock` (
`id` int(11) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`age` int(11) NOT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_age` (`age`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Insert into t1_deadlock(id,name,age,address) values (1,'刘备',18,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (2,'关羽',17,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (3,'张飞',16,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (4,'关羽',16,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (5,'诸葛亮',35,'蜀国');
Insert into t1_deadlock(id,name,age,address) values (6,'曹孟德',32,'魏国');
Time | Transaction1 | Transaction2 |
---|---|---|
T1 | begin; | begin; |
T2 | select * from t1_deadlock where id=1 for update; | |
T3 | delete from t1_deadlock where id=5; | |
T4 | update t1_deadlock set name=‘qqq’ where id=5; | |
T5 | delete from t1_deadlock where id=1; | |
T6 | 死锁 | 死锁 |
-- Session01
begin;
select * from t1_deadlock where id=1 for update;
update t1_deadlock set name='qqq' where id=5;
commit;
-- Session02
begin;
delete from t1_deadlock where id=5;
delete from t1_deadlock where id=1;
-- 死锁
commit;
上图紫色表示当前事务持有的锁,红色表示需要等待花获取的锁。我们按照表中是执行顺序,首先事务1给1这条记录加了记录锁,然后事务2给5这条记录加了记录锁,这个时候事务1又想取更新记录5就需要等待事务2提交释放5的记录锁,同样事务2想要删除记录为1的数据也需要等待事务1提交释放1记录的锁。这样事务1等待事务2,事务2等待事务1就造成了死锁。
SHOW ENGINE INNODB STATUS;
Time | Transaction1 | Transaction2 |
---|---|---|
T1 | begin; | begin; |
T2 | delete from t2_deadlock where cnt=‘abc-130-sz’; | |
T3 | delete from t2_deadlock where cnt=‘abc-130-sz’; | |
T4 | insert into t2_deadlock (cnt) values (‘abc-130-sz’); | |
T5 | 死锁 | 死锁 |
CREATE TABLE `t2_deadlock` ( `id` int(11) NOT NULL AUTO_INCREMENT, `cnt` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`), UNIQUE index `idx_cnt` (`cnt`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; insert into t1_deadlock03(id,cnt) values (1,'abc-130-sz'); `` ```sql -- Session01 begin; delete from t2_deadlock where cnt='abc-130-sz'; insert into t2_deadlock(cnt) values ('abc-130-sz'); commit; -- Session02 begin; delete from t2_deadlock where cnt='abc-130-sz'; commit;
事务1持有了这条记录的写锁,然后插入的时候由于需要先当前读最新的数据,所以需要加读锁,但是写锁是排它的就需要等待写锁释放,但是写锁只有在事务提价的时候才会释放,因此产生了死锁。
MySQL默认会主动探知死锁,并回滚某一个影响最小的事务。等另一事务执行完成之后,再重新执行该事务。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。