首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么插入重复键错误创建共享锁?

为什么插入重复键错误创建共享锁?
EN

Database Administration用户
提问于 2021-02-26 06:41:09
回答 1查看 500关注 0票数 0

在mysql 文档中,下面是锁定插入的示例:

INSERT设置插入行的独占锁。如果发生重复键错误,则在重复索引记录上设置共享锁.如果有多个会话试图插入同一行(如果另一个会话已经具有独占锁),则共享锁的这种使用会导致死锁。

这是通过以下示例进行的:

代码语言:javascript
复制
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;

第1场会议:

代码语言:javascript
复制
START TRANSACTION;
INSERT INTO t1 VALUES(1)

第2场会议:

代码语言:javascript
复制
START TRANSACTION;
INSERT INTO t1 VALUES(1)

第3场会议:

代码语言:javascript
复制
START TRANSACTION;
INSERT INTO t1 VALUES(1)

第1场会议:

代码语言:javascript
复制
ROLLBACK;

将发生以下情况:

会话1的第一个操作获取行的独占锁。会话2和会话3的操作都会导致重复键错误,并且它们都会请求行的共享锁。当会话1回滚时,它会释放该行上的独占锁,并授予会话2和3的排队共享锁请求。此时,会话2和3死锁:由于对方持有的共享锁,这两个会话都不能为该行获取排他锁。

这让我想知道,为什么一个人首先需要一个共享锁来进行独占锁?将行为更改为:

INSERT设置插入行的独占锁。如果发生重复键错误,则会设置重复索引记录上的exclusive锁

如果像这样处理它,那么在上面的示例中,将不会出现死锁,会话2或会话3(取决于谁首先获得独占锁)将尝试继续。假设会话2首先锁定,然后失败和回滚,然后会话3将尝试插入。这样做不更有意义吗?

EN

回答 1

Database Administration用户

发布于 2021-11-07 17:06:25

我宁愿从实际的角度来看待它。

  • 我的事务处理越快,它们遇到锁定问题的可能性就越小。
  • 不是所有的死锁都是可以避免的所以..。
  • 我应该始终检查错误(如“死锁”),并准备重新运行我的事务。
  • InnoDB非常擅长发现死锁并快速回滚其中一个事务。
  • 某些冲突是“锁等待”冲突(而不是死锁),并将通过将一个事务推迟到另一个事务完成时默默地解决。
  • 当我不知道发生了什么事情时,我将其归因于InnoDB的谨慎,甚至导致可能需要的更多的锁定。

最后一项可能是您遇到的--一种复杂的情况,在这种情况下,InnoDB保守地取出了一个比所需要的更强的锁。

请注意,InnoDB希望速度更快。因此,即使一个复杂的反死锁算法是可能的,InnoDB可能会使用一种更简单、更快但仍然“安全”的算法。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/286061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档