度小满面试:mysql插入会导致死锁吗?

会的,很多人以为只有更新的情况下才会造成死锁,比如下面2个事务同时执行形成了互相等待。其实插入也会。站长收到反馈头部金融类公司开发特别喜欢问这个问题。

事务一执行:
UPDATE inventory SET stock = stock - 10 WHERE id = 1;
UPDATE inventory SET stock = stock - 10 WHERE id = 2;
事务二执行
UPDATE inventory SET stock = stock - 10 WHERE id=2;
UPDATE inventory SET stock = stock - 10 WHERE id = 1;

insert 唯一键冲突

我就先和你分享一个经典的死锁场景。

在 session A 执行 rollback 语句回滚的时候,session C 几乎同时发现死锁并返回。这个死锁产生的逻辑是这样的:

在 T1 时刻,启动 session A,并执行 insert 语句,此时在索引 c 的 c=5 上加了记录锁。注意,这个索引是唯一索引,因此退化为记录锁。

在 T2 时刻,session B 要执行相同的 insert 语句,发现了唯一键冲突,加上读锁;同样地,session C 也在索引 c 上,c=5 这一个记录上,加了读锁。

T3 时刻,session A 回滚。这时候,session B 和 session C 都试图继续执行插入操作,都要加上写锁。两个 session 都要等待对方的行锁,所以就出现了死锁。

这个流程的状态变化图如下所示。

如何避免?

1 关于insert造成死锁的情况,我之前做过测试,事务1并非只有insert,delete和update都可能造成死锁问题,核心还是插入唯一值冲突导致的.我们线上的处理办法是 1 去掉唯一值检测 2减少重复值的插入 3降低并发线程数量

#mysql##java##面试#
全部评论

相关推荐

nbdy:字太多了,写简历不是写自传,亮点难点技能点列出来就行,要简明扼要
点赞 评论 收藏
分享
评论
点赞
7
分享

创作者周榜

更多
牛客网
牛客企业服务