我有一个mysql表:
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`value` int(10) unsigned NOT NULL,
`idxvalue` int(10) unsigned NOT NULL,
`ukvalue` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_value` (`ukvalue`),
KEY `idx_value` (`idxvalue`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
并且我在表中插入了两行:
insert into test (id, value, idxvalue, ukvalue) values (10, 1, 3, 3);
insert into test (id, value, idxvalue, ukvalue) values (20, 1, 3, 4);
然后我创建了一个事务(Transaction1):
> begin;
> insert into test (id, value, idxvalue, ukvalue) values (9, 1, 3, 3);
ERROR 1062 (23000): Duplicate entry '3' for key 'uk_value'
> delete from test where ukvalue = 3;
Query OK, 1 row affected (0.00 sec)
然后我创建了另一个事务(Transaction2):
> insert into test (id, value, idxvalue, ukvalue) values (13, 1, 3, 3);
然后我回到Transaction1,然后运行:
> insert into test (id, value, idxvalue, ukvalue) values (14, 1, 3, 3);
Query OK, 1 row affected (0.00 sec)
> delete from test where ukvalue = 3;
Query OK, 1 row affected (0.00 sec)
同时,在Transaction2中,我得到了:
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
为什么在这里发生僵局?谢谢
环境:MySQL的5.7.28-0linux ubuntu0.18.04.4
请检查“ SHOW ENGINE INNODB STATUS”以查看有关死锁的详细信息。
[当执行查询“从ukvalue = 3的测试中删除”时,事务1使用模式“ X锁定记录但不间隔”锁定了ukvalue = 3的索引。
[当您执行查询“插入测试(id,值,idxvalue,ukvalue)值(13、1、3、3)”时,事务2开始等待以模式S获得ukvalue = 3的索引锁。 2现在正在等待事务1释放X锁。
[当您在事务1中执行其余查询时,事务1试图以ukvalue = 3的方式获取另一个索引锁定,其方式为“在等待插入插入意图之前锁定间隙”。事务1现在正在等待事务2释放S锁。
事务2现在正在等待事务1,事务1正在等待事务2。这是一个僵局。