MySQL锁定重复键错误

docs

If a duplicate-key error occurs, a shared lock on the duplicate index
record is set. This use of a shared lock can result in deadlock should
there be multiple sessions trying to insert the same row if another
session already has an exclusive lock. This can occur if another
session deletes the row.

继续使用文档中的示例,

假设InnoDB表t1具有以下结构:

CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;

现在假设三个会话按顺序执行以下操作:

第一节:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

第二节:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

第3节:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

第一节:

ROLLBACK;

The first operation by session 1 acquires an exclusive lock for the
row. The operations by sessions 2 and 3 both result in a duplicate-key
error and they both request a shared lock for the row. When session 1
rolls back, it releases its exclusive lock on the row and the queued
shared lock requests for sessions 2 and 3 are granted. At this point,
sessions 2 and 3 deadlock: Neither can acquire an exclusive lock for
the row because of the shared lock held by the other.

我有一些问题 :

1)insert查询对其插入的行进行独占锁定.因此,假设T1插入第1行,它将锁定第1行.现在,当T2开始写入时,INNODB会在执行之前评估查询,并发现它将写入相同的PK(i = 1的行)让T2等待?或者它会开始执行T2并发现它会出现重复键错误或PK违规.

2)为什么T2和T3采用共享锁?插入过程*享锁如何进入画面?

解决方法:

1) The insert query takes an exclusive lock on the row it is
inserting. So, suppose T1 is inserting on row 1, it will lock row 1.
Now when T2 comes to write, will INNODB evaluate the query before
executing it and find out that it is going to write the same PK (row
with i = 1) and make T2 wait? Or will it start execution of T2 and
find that it gives duplicate key error or PK violation.

我认为你正在简化术语/过程.在解析查询之后并且在执行查询之前,它需要获取必要的锁.正是在这一点上,确定:

>会话1获取独占锁,因为它正在插入并且没有其他锁
>会话2和3排队等待共享锁,因为会话1已经保留了独占锁,并且会话2和3处于重复键错误

2) Why are T2 and T3 taking shared locks? How do shared locks come
into picture during insert?

上面,会话2和3排队等待共享锁,因为它们是重复键错误.但是,当会话1删除密钥并释放独占锁时,现在会话2和3都被授予共享锁.此时,两者都尝试获取独占锁以完成插入.但是,没有人可以,因为另一个人已经持有共享锁.因此,不会授予独占锁定,并且它们会死锁.

上一篇:Python – 多线程 – Lock必须是全局的吗?


下一篇:MySQL MyISAM中的“系统锁定”