从文档:
如果出现重复键错误,则会在重复索引记录上设置一个共享锁。如果有多个会话试图插入同一行(如果另一个会话已经具有互斥锁),则使用共享锁可能会导致死锁。如果另一个会话删除该行,则会发生这种情况。
结合文档中的示例,
假设InnoDB表t1具有以下结构:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
Run Code Online (Sandbox Code Playgroud)
现在,假设三个会话按顺序执行以下操作:
第一场:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第二场:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第三节:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Run Code Online (Sandbox Code Playgroud)
第一场:
ROLLBACK;
Run Code Online (Sandbox Code Playgroud)
会话1的第一个操作获取该行的排他锁。会话2和3的操作都导致重复键错误,并且都请求该行的共享锁。会话1回滚时,它将释放该行的排他锁,并为会话2和3排队等待共享锁请求。此时,会话2和3死锁:由于另一个持有共享锁,因此两个都无法获得该行的排他锁。
我有一些问题 :
1)insert查询对其插入的行进行排他锁。因此,假设T1正在插入第1行,它将锁定第1行。现在,当T2开始写入时,INNODB将在执行查询之前对查询进行评估,并发现它将要写入相同的PK(i = 1的行)让T2等待?还是将开始执行T2并发现它给出了重复的键错误或PK违反。
2)为什么T2和T3采取共享锁?插入期间如何看到共享锁?