MySQL 在 REPEATABLE READ 隔离级别下是可以解决幻读问题的,解决方案有两种,可以使用 MVCC 方案解决,也可以采用加锁方案解决。但是在使用加锁方案解决时有问题,就是事务在第一次执行读取操作时,那些幻影记录尚不存在,我们无法给这些幻影记录加上记录锁。InnoDB 提出了一种称之为 Gap Locks 的锁,官方的类型名称为:LOCK_GAP,我们也可以简称为 gap 锁。
间隙锁实质上是对索引前后的间隙上锁,不对索引本身上锁。
- Gap在read commited或者更低级别的事务下是没有的,所以read commited 与read uncommited无法避免幻读。
- 锁定一个范围,但不包含该记录本身。
- **Gap是左开右闭的
1.Gap锁用在主键索引或者唯一索引的情况
- 如果where条件全部命中, 则不会用Gap锁, 只会加行锁
- 如果where条件部分命中或者全不命中, 则会加Gap锁
2.Gap锁会用在非唯一索引(普通索引)或者不走索引的当前读中
1.非唯一索引的情况
2.不走索引的情况
会对所有gap全部上锁