问个MySQL的问题

InnoDB,可重复读场景
有一个自增主键的表,如果同时执行update xx where id > 1和insert语句(不带主键),会不会冲突?

8 个赞

应该不会,update操作有锁,insert会被阻塞

7 个赞

你说的冲突是指什么?

  • 事务是否被 block?
  • 还是说 update 是否会成功修改新 insert 的 row ?修改不成功算是冲突?

首先 update 和 insert 都是「当前读」,在 MySQL 的「Repeatable Read」隔离级别下,是能防止「当前读」的「幻读」问题,实现的手段是 Gap Lock。

你的情况是,那个事务先拿到 Gap Lock,其他事务就会被 Block。

2 个赞

我理解insert会被update阻塞, 但如2L我也问了GPT说不会冲突,就很奇怪

1 个赞

你这个回复是违反论坛规则的,不能全部使用AI的回复。

已删 :joy:

理论上是不会的,执行有先后顺序的

在讨论两个独立事务的提交顺序时,考虑到这里都是DML操作,语句1会使用谓词锁定(Gap Lock),语句2同样使用Gap Lock;在两个事务提交时,MySQL基于SS2PL保障事务提交的先后顺序,所以两个事务的执行结果取决于谁前提交。
进一步的,这里的事务存在竟态条件,建议优化;同时考虑到 insert 参与的并发事务,这里是有自增ID分发的冲突(不连续)的可能(具体取决于数据库自增ID分发配置)。

如果update的事务没有commit,则会阻塞,mysql5.7.44测试
表中数据只有2条


会话1模拟update事务,但是不执行commit

会话2执行insert事务,但是没有返回

只有当会话1执行完commit后,会话2的insert才有返回

20 个赞

id > 1锁表了吧?

更新除了id为1的所有行

如果当前插入的id自增长后大于1,会阻塞的,锁表说法也有点不对,应该是行锁,只是覆盖了id大于1的所有行

2 个赞

rr 事务级别下,update where id > 1 会对最后一行施加间隙锁防止插入。insert 时会施加行锁。所以两个事务存在锁竞争,另一个事务需要等待先获取锁的事物释放锁,才能往下执行

1 个赞

感谢!!