2022-04-24 13:30:33
间隙锁是InnoDB在可重复读隔离级别下为防止幻读而锁定索引间隙的机制,阻止其他事务在区间内插入新记录。以下是对间隙锁的详细解释:
间隙锁的定义:
间隙锁是InnoDB存储引擎在可重复读(REPEATABLE READ)隔离级别下使用的一种锁机制。
它锁定的不是某一条具体的记录,而是索引之间的“间隙”。例如,如果一个索引包含值10、20、30,那么间隙就包括(10, 20)和(20, 30)这些区间。
间隙锁的作用:
间隙锁的核心目的是解决“幻读”问题。幻读是指在一个事务中两次查询结果不一致,多出了一些本不该出现的记录。
通过锁定索引之间的空隙,MySQL可以阻止其他事务插入新行,从而保证范围查询的一致性。
例如,执行语句SELECT * FROM users WHERE age = 25 FOR UPDATE;,如果age=25的记录不存在,InnoDB仍可能对(20,30)这个索引间隙加锁,防止其他事务插入age=25的记录。
间隙锁的使用条件:
间隙锁只在特定条件下生效:使用的是InnoDB引擎,事务隔离级别为可重复读(RR)或以上。
执行的是范围查询(如WHERE age BETWEEN 20 AND 30)或等值查询但记录不存在时,且语句使用了索引;若走全表扫描,间隙锁可能退化为表锁。
间隙锁的影响:
虽然间隙锁有助于一致性,但也可能带来性能问题。它容易导致锁冲突,降低并发性能。
间隙锁可能导致死锁,特别是在多个事务按不同顺序访问数据时。
在高并发插入场景下,间隙锁可能阻塞正常写入操作。
如果不需要严格的幻读防护,可以考虑将隔离级别降为读已提交(READ COMMITTED),此时InnoDB通常不会使用间隙锁。
间隙锁与记录锁、临键锁的关系:
间隙锁与记录锁结合可以形成临键锁(Next-Key Lock),实现更完整的并发控制。
记录锁锁定的是索引中的具体记录,而间隙锁锁定的是记录之间的间隙。临键锁则同时锁定记录和间隙,提供更强的保护。