mysql - 为什么会发生mysql死锁?
问题描述
我有一个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
我在表中插入 2 行:
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-0 linux ubuntu0.18.04.4
解决方案
请检查“SHOW ENGINE INNODB STATUS”以查看有关死锁的详细信息。
当您执行查询“delete from test where ukvalue = 3”时,事务 1 锁定 ukvalue = 3 的索引,锁定模式为“X locks rec but not gap”。
当您执行查询“insert into test (id, value, idxvalue, ukvalue) values (13, 1, 3, 3)”时,事务 2 开始等待以模式 S 获取 ukvalue = 3 的索引锁定。事务 2 是现在等待事务 1 释放 X 锁。
当您在事务 1 中执行其余查询时,事务 1 尝试使用“在 rec 插入意图等待之前锁定间隙”模式为 ukvalue = 3 获取另一个索引锁。事务 1 现在正在等待事务 2 释放 S 锁。
事务 2 现在正在等待事务 1,而事务 1 正在等待事务 2。这是一个死锁。
推荐阅读
- ms-access - 访问相当于导入电子表格向导的 VBA
- google-apps-script - 复制现有条件格式规则集时,条件格式规则引用另一个工作表
- sas - PROC SQL Where 条件
- javascript - JavaScript:使用嵌套对象和数组获取对象参数并返回字符串元素的计数
- javascript - 如何将此文件路由正确添加到 tsconfig.json 以消除此错误?
- php - dotenv 值未正确读取
- google-cloud-firestore - FirestoreException - 找不到 TLS ALPN 提供程序 - 没有工作的 netty-tcnative
- azure-devops - azure pipelines.yml 使用带有 azure cli 和 python 3 的 vm?
- javascript - 尝试在那时测试我的 catch 块没有成功
- css - 自定义组合框中的默认文本