首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么提交不会导致死锁

为什么提交不会导致死锁
EN

Stack Overflow用户
提问于 2016-08-26 01:11:27
回答 1查看 237关注 0票数 2

我读过关于InnoDB锁的mysql参考手册。我得到了:(出发地:http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html)

INSERT设置插入行的独占锁。此锁是索引记录锁,而不是下一个键锁(即没有间隙锁),也不会阻止其他会话插入插入行之前的间隙。

在插入行之前,设置称为插入意图间隙锁的间隙锁类型。此锁指示要以这样的方式插入多个事务,即插入到同一索引间隙中的多个事务不需要等待对方,如果它们不在间隙内的相同位置插入。假设有值为4和7的索引记录。在获得插入行的独占锁之前,尝试插入值为5和6的单独事务在获得插入行的排他锁之前,分别将4和7之间的间隔锁定为insert意图锁,但不要彼此阻塞,因为行是不冲突的。

如果发生重复键错误,则在重复索引记录上设置共享锁.如果有多个会话试图插入同一行(如果另一个会话已经具有独占锁),则共享锁的这种使用会导致死锁。如果另一个会话删除行,则可能发生这种情况。假设InnoDB表t1具有以下结构:

创建表t1 ( INT,主键(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死锁:由于对方持有的共享锁,这两个会话都不能为该行获取排他锁。

我做了一个实验,我发现这是事实。

我的问题是:

(1)我发现,如果提交会话1,则不会发生死锁。为什么?当我提交会话1时,X行锁也将被释放。所以我不明白。

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2016-08-26 02:48:57

我怀疑这是一种边缘情况,不值得提高效率。请注意,您必须得到三个会话试图抓取同一行-一个罕见的发生。你做了回滚--也是很少见的。因此,所发生的死锁是过份的,但不值得修正。因此,人们必须准备好在任何地方处理死锁。

FYI,如果这是Galera集群的3个节点,那么COMMIT上就会出现代码必须处理的错误。如果对多个节点多次应用此事务(使用回滚或提交),我怀疑会发生更多奇怪的事情。

现在请回答你的问题..。据推测,死锁不会发生,因为其中一个线程获得了独占锁,而另一个线程被“等待”而不是“死锁”击中。

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

https://stackoverflow.com/questions/39156969

复制
相关文章

相似问题

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