MySQL间隙锁触发是否有明确规则?其触发逻辑是否具确定性?
MySQL间隙锁触发规则与确定性说明
核心前提
间隙锁(Gap Lock)是InnoDB仅在可重复读(RR)隔离级别下启用的锁机制,读提交(RC)及更低级别默认关闭该锁(手动开启innodb_locks_unsafe_for_binlog的场景除外,不建议生产环境使用)。
明确的触发规则
- 锁定读语句触发:执行
SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE这类锁定读时,若查询条件针对非唯一索引/无索引字段,InnoDB会对满足条件的记录区间添加间隙锁,阻止其他事务插入该区间内的新数据,避免幻读。
示例:假设user表的age字段为非唯一索引,执行SELECT * FROM user WHERE age BETWEEN 20 AND 30 FOR UPDATE,InnoDB会锁定age值对应的三个间隙:(小于20的最大存在值, 20)、(20, 30)、(30, 大于30的最小存在值),而非仅锁定现有20-30的记录。 - 唯一索引的特殊处理:若查询条件是唯一索引(含主键)的精确匹配,仅会添加记录锁,不会触发间隙锁;但如果是唯一索引的范围查询(如
SELECT * FROM user WHERE id > 100 FOR UPDATE),仍会对匹配记录后的间隙加锁。 - 隐式触发场景:处理外键约束检查、自增字段插入时,InnoDB会自动添加间隙锁,保障数据完整性。
触发逻辑的确定性
间隙锁的触发逻辑完全由InnoDB的Next-Key Lock(临键锁,记录锁+间隙锁的组合)算法决定,锁的范围是根据索引树结构精确计算的:
- 针对非唯一索引,Next-Key Lock会锁定当前匹配记录的前一个间隙到后一个间隙的完整区间;
- 针对唯一索引的精确查询,Next-Key Lock会退化为单纯的记录锁,不包含间隙;
- 所有锁的范围都可通过
INFORMATION_SCHEMA.INNODB_LOCKS和INNODB_LOCK_WAITS视图查询验证,不存在随机触发的情况。
所谓“非必要场景触发间隙锁”,本质是对Next-Key Lock的区间范围判断有误——这类间隙锁是RR级别下防止幻读的必要机制,并非无规则的误触发。
内容的提问来源于stack exchange,提问作者user19481364
相关产品推荐
相关产品推荐

