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的回复。
已删
理论上是不会的,执行有先后顺序的
在讨论两个独立事务的提交顺序时,考虑到这里都是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 个赞
感谢!!