当多个事务同时插入相同的值时,为什么除了一个会出现重复异常?

问题描述 投票:0回答:1

我不明白本文档的

INSERT sets an exclusive lock on the inserted row.
部分内容。
https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

在下面的部分,

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);

我以为他们会按照下面的顺序来

  1. 第一个事务获得了第 1 行的独占锁。(尚未提交)
  2. 第二个事务也尝试获得独占锁。
  3. 第二个事务将等待,因为第一个事务已经拥有排他锁。

但是他们不喜欢上面的内容,文件说

会话 2 和 3 的操作都会导致重复键错误,并且都请求该行的共享锁。

我不明白为什么他们会出现重复的异常。
为了发生重复错误,该行必须已经提交。
但他们没有。第一笔交易尚未提交。

mysql insert locking
1个回答
0
投票

我怀疑这是因为在插入唯一值(唯一索引)之前,InnoDB必须进行搜索(二级索引扫描),这将创建下一个键锁(下一个键锁=记录锁+间隙锁)。

因为存在间隙锁,所以在进行插入操作时,需要事务先获取插入意向锁。此锁的目的只是允许不同的事务在行不重复的情况下同时将行插入到间隙中。如果行重复,则会引发重复键错误。

在此示例中,事务 1 获取了从最小值到 1 的下一键锁,然后对 1 进行排他锁并在提交之前插入该行。事务 2 和 3 获得了插入意向锁,因为存在下一键锁,并且它们意识到它们的插入是彼此重复的。

© www.soinside.com 2019 - 2024. All rights reserved.