我不明白本文档的
INSERT sets an exclusive lock on the inserted row.
部分内容。在下面的部分,
Session 1:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 2:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
我以为他们会按照下面的顺序来
但是他们不喜欢上面的内容,文件说
会话 2 和 3 的操作都会导致重复键错误,并且都请求该行的共享锁。
我不明白为什么他们会出现重复的异常。
为了发生重复错误,该行必须已经提交。
但他们没有。第一笔交易尚未提交。
我怀疑这是因为在插入唯一值(唯一索引)之前,InnoDB必须进行搜索(二级索引扫描),这将创建下一个键锁(下一个键锁=记录锁+间隙锁)。
因为存在间隙锁,所以在进行插入操作时,需要事务先获取插入意向锁。此锁的目的只是允许不同的事务在行不重复的情况下同时将行插入到间隙中。如果行重复,则会引发重复键错误。
在此示例中,事务 1 获取了从最小值到 1 的下一键锁,然后对 1 进行排他锁并在提交之前插入该行。事务 2 和 3 获得了插入意向锁,因为存在下一键锁,并且它们意识到它们的插入是彼此重复的。