为什么会发生mysql死锁?

问题描述 投票:0回答:1

我有一个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

mysql transactions locking deadlock
1个回答
0
投票

请检查“ 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。这是一个僵局。

© www.soinside.com 2019 - 2024. All rights reserved.