从文档:
如果发生重复键错误,则在重复索引记录上设置共享锁。如果另一个会话已经拥有排它锁,那么如果有多个会话尝试插入同一行,则使用共享锁可能会导致死锁。如果另一个会话删除该行,就会发生这种情况。
使用文档中的示例,
假设 InnoDB 表 t1 具有以下结构:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
Run Code Online (Sandbox Code Playgroud)
现在假设三个会话依次执行以下操作:
第 1 节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第 2 节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第 3 节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第 1 节:
ROLLBACK;
Run Code Online (Sandbox Code Playgroud)
会话 1 的第一个操作获取该行的排它锁。会话 2 和 3 的操作都会导致重复键错误,并且它们都为该行请求共享锁。当会话 1 回滚时,它会释放它对该行的排它锁,并且会话 2 和 3 的排队共享锁请求被授予。此时,会话 2 和 3 死锁:由于对方持有共享锁,因此都无法获取该行的排他锁。
我有一些问题 :
1) 插入查询对其插入的行进行排他锁。因此,假设 T1 在第 1 行插入,它将锁定第 1 行。现在当 …