MySQL

RR 下的范围 UPDATE,会把还不存在的行也锁住

表里只有 id = 1 和 id = 5。事务 A 执行范围更新后不提交,B 来插入 id = 3:

sql
-- A
BEGIN;
UPDATE t SET c = c + 1 WHERE id BETWEEN 1 AND 5;

-- B
INSERT INTO t VALUES (3, 0);
隔离级别B 的 INSERT
REPEATABLE READ等锁,超时报 1205
READ COMMITTED立刻成功

RR 会把扫过的间隙锁到事务结束,挡住往这段范围里插新行(防幻读)。RC 只锁存在的行。

快照只管普通 SELECT;UPDATE、DELETE、FOR UPDATE 这些会加锁的语句,才是间隙锁的来源。RC 下也不是完全没有间隙锁:外键检查和唯一键冲突时仍会加。

esc