【发布时间】:2016-10-24 16:25:25
【问题描述】:
来自docs:
如果发生重复键错误,重复索引上的共享锁 记录被设定。这种共享锁的使用可能会导致死锁 如果另一个会话尝试插入同一行,则有多个会话 session 已经有一个独占锁。如果另一个 session 删除该行。
使用文档中的示例,
假设 InnoDB 表 t1 具有以下结构:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
现在假设三个会话依次执行以下操作:
第 1 节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
第 2 节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
第三节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
第 1 节:
ROLLBACK;
会话 1 的第一个操作为 排。会话 2 和 3 的操作都导致重复键 错误,他们都请求该行的共享锁。当会话 1 回滚,它释放对行和排队的排他锁 会话 2 和 3 的共享锁请求被授予。在此刻, 会话 2 和 3 死锁:两者都无法获得独占锁 该行是因为对方持有的共享锁。
我有一些问题:
1) 插入查询在它正在插入的行上获取一个排他锁。因此,假设 T1 在第 1 行插入,它将锁定第 1 行。现在当 T2 开始写入时,INNODB 将在执行之前评估查询并发现它将写入相同的 PK(i = 1 的行)让T2等待?或者它会开始执行 T2 并发现它给出了重复的密钥错误或 PK 违规。
2) 为什么 T2 和 T3 使用共享锁?共享锁如何在插入过程中出现?
【问题讨论】:
-
添加一些
SLEEP(10)函数调用来做一个测试用例;然后我们可以进一步讨论这个问题。包括SHOW ENGINE INNODB STATUS;的相关部分。
标签: mysql concurrency transactions locking