在mysql 文档中,下面是锁定插入的示例:
INSERT设置插入行的独占锁。如果发生重复键错误,则在重复索引记录上设置共享锁.如果有多个会话试图插入同一行(如果另一个会话已经具有独占锁),则共享锁的这种使用会导致死锁。
这是通过以下示例进行的:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;第1场会议:
START TRANSACTION;
INSERT INTO t1 VALUES(1)第2场会议:
START TRANSACTION;
INSERT INTO t1 VALUES(1)第3场会议:
START TRANSACTION;
INSERT INTO t1 VALUES(1)第1场会议:
ROLLBACK;将发生以下情况:
会话1的第一个操作获取行的独占锁。会话2和会话3的操作都会导致重复键错误,并且它们都会请求行的共享锁。当会话1回滚时,它会释放该行上的独占锁,并授予会话2和3的排队共享锁请求。此时,会话2和3死锁:由于对方持有的共享锁,这两个会话都不能为该行获取排他锁。
这让我想知道,为什么一个人首先需要一个共享锁来进行独占锁?将行为更改为:
INSERT设置插入行的独占锁。如果发生重复键错误,则会设置重复索引记录上的exclusive锁。
如果像这样处理它,那么在上面的示例中,将不会出现死锁,会话2或会话3(取决于谁首先获得独占锁)将尝试继续。假设会话2首先锁定,然后失败和回滚,然后会话3将尝试插入。这样做不更有意义吗?
发布于 2021-11-07 17:06:25
我宁愿从实际的角度来看待它。
最后一项可能是您遇到的--一种复杂的情况,在这种情况下,InnoDB保守地取出了一个比所需要的更强的锁。
请注意,InnoDB希望速度更快。因此,即使一个复杂的反死锁算法是可能的,InnoDB可能会使用一种更简单、更快但仍然“安全”的算法。
https://dba.stackexchange.com/questions/286061
复制相似问题