You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SERIALIZABLE隔离级别下并发执行指定SQL逻辑是否存在问题?

问题背景

隔离级别:SERIALIZABLE

执行逻辑步骤:

  1. select other_col from my_table where pk_col = 1 for update
  2. 若步骤1未返回任何行则跳转至步骤3,否则跳转至步骤5
  3. insert ignore into my_table(pk_col, other_col) values(1, 10)
  4. select other_col from my_table where pk_col = 1 for update
  5. update my_table set other_col = other_col + 10 where pk_col = 1

用户疑问

当多个事务并发执行上述逻辑时,是否会出现死锁、数据不一致等问题?用户认为每条语句都会获取pk_col=1的排他锁,因此至少不会出现死锁和数据不一致的情况。


分析结果

死锁:确实会发生

在SERIALIZABLE隔离级别下,并发场景下的死锁风险不可忽视:

  • 当所有事务执行步骤1时,若pk_col=1的行不存在,InnoDB会在该主键值对应的间隙上添加间隙锁(Gap Lock)。
  • 多个事务持有该间隙锁后,都会进入步骤3执行insert ignore。插入操作需要获取插入意向锁,但间隙锁与插入意向锁互斥,导致多个事务互相等待对方释放锁资源,最终触发死锁——MySQL会自动选择其中一个事务回滚来解除死锁。

数据一致性:不会出现问题

只要事务能正常完成(死锁回滚后重新执行也算),数据不会出现不一致:

  • 不管是select ... for update、insert ignore还是update,针对pk_col=1的行(或对应间隙)都会持有排他性锁(行锁或间隙锁),确保同一时间只有一个事务能修改该行数据。最终other_col的数值会和事务成功执行的次数完全匹配,不会出现丢失更新等不一致情况。

对用户观点的修正

用户关于数据一致性的判断是正确的,但认为不会出现死锁的结论有误——间隙锁和插入意向锁的冲突是引发死锁的核心原因。


内容的提问来源于stack exchange,提问作者firia2000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:42:10