分析&回答
间隙锁为了解决RR(可重复读)级别下当前读导致的幻读问题,锁的对象是索引叶子节点的next指针。
快照读
在RR隔离级别下:快照读有可能读到数据的历史版本,也有可能读到数据的当前版本。所以快照读无需用锁也不会发生幻读的情况。
当前读
- 当前读:select…lock in share mode,select…for update
- 当前读:update,delete,insert
- 当前读读取的是记录的最新版本,需要通过加锁(行锁、间隙锁、表锁)的方式,使得被当前读读过的数据不能被新增修改或者删除,换句话说再来一次当前读要返回相同的数据。
数据库 X
a 主键 | b 索引 | c 字段 |
---|---|---|
1 | 2 | A |
3 | 6 | B |
5 | 4 | C |
7 | 10 | D |
9 | 8 | E |
间隙锁范围
select c from X where a=4 for update;
会锁住主键索引叶子节点的3的next指针。
select c from X where a=3 for update;
间隙锁会退化为行锁只锁叶子节点3 ,为什么因为没必要。
select c from X where a>4 for update;
叶子节点3及之后所有节点会加行锁并且他们的next指针会加锁,
select a from X where c=2 for update;
会发生锁表,因为c没有索引结构能存储行锁或者间隙锁。
反思&扩展
- mysql中尽量不要使用区间更新。
- 需要更新的情况使用 ID = X
- 查询也尽量通过 ID 去查
喵呜面试助手: 一站式解决面试问题,你可以搜索微信小程序 [喵呜面试助手] 或关注 [喵呜刷题] -> 面试助手 免费刷题。如有好的面试知识或技巧期待您的共享!