暂无图片
两个会话update同一行出现死锁
我来答
分享
Mr jun
2022-03-31
两个会话update同一行出现死锁

1、隔离级别:READ-COMMITTED

2、两个会话中处理一条update无其他任何sql

3、经过处理的表结构如下,记录数8万+

    CREATE TABLE `tab01` (

`id` int NOT NULL AUTO_INCREMENT,
`a` bigint DEFAULT NULL,
`b` varchar(32),
`c` varchar(32),
`d` varchar(32),
`e` varchar(32),
`f` varchar(32),
PRIMARY KEY (`id`),
KEY `inx_tab01_b` (`b`),
KEY `idx_tab01_a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='xxx';


4、两个会话执行的update的sql:UPDATE tab01 SET c='4',d='2022-03-30 18:10:51.389' WHERE b = 'xxxxxxxx'; 走inx_tab01_b索引,且b列值唯一的


5、死锁信息如下

    会话一:拿到inx_tab01_b索引锁,等待PRIMARY锁

    会话二:拿到PRIMARY锁,等待inx_tab01_b索引锁


个人疑问:按照拿锁顺序应该是先拿inx_tab01_b索引锁,再拿主键索引,当并发的时候应该出现锁的等待,为什么会出现死锁呢?

我来答
添加附件
收藏
分享
问题补充
2条回答
默认
最新
Mr jun

mysql版本是 mysql 8.0.25

暂无图片 评论
暂无图片 有用 0
打赏 0

感觉我也遇到如此的问题, MYSQL 更新操作对二级索引都要加锁,主键和二级索引加锁顺序可以不一致.
这要大神翻源码来看了.

从常理来说, 更新 非索引字段,而该行其它字段上的索引可以不用加锁的.

这是MYSQL代码的问题吧 默认下是RR事务, 根据B字段的索引去找数据,先给B索引加锁 为防止啥? 我也不知道.
我这边遇到情况也类似,不过我的B是唯一索引. 你的B不是唯一索引.

加主键锁,还是加索引锁,能加到谁就加到谁.

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交