前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >加锁规则

加锁规则

作者头像
用户7447819
发布2021-07-23 14:28:42
8260
发布2021-07-23 14:28:42
举报
文章被收录于专栏:面试指北面试指北

加锁规则

间隙锁只有在可重复读的隔离级别下有效。

1. 两个原则

  • 加锁的单位是 next-key lock,这个区间是前开后闭。
  • 查找过程中访问的对象才会加锁。

2. 两个优化

  • 在索引上的等值查询(where ... = ...),如果加锁的对象是唯一索引,则next-key lock的将会退化为行锁。
  • 在索引上的等值查询,向右遍历的时候,如果最后一个值不满足条件的话,则next-key lock 会退化,变成间隙锁(前开后开区间)。

3. 一个Bug

唯一索引上的范围查询,会访问到第一个不满足条件的数据为止。

4. 举个例子

代码语言:javascript
复制
CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `c` (`c`)
) ENGINE=InnoDB;
 
insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

4.1 next-key 退化为行锁

  • session A 查找id=10的时候,本来的加锁范围是(0,10],根据原则1退化为行锁加锁范围变成行锁id=10。
  • session A向后查找的过程中的间隙锁为(10,15]
  • 综合来看sessionA的加锁范围为[10,15]
  • 因此 sessionB的insert into t values (8,8,8)不会锁住,而(13,13,13)会被锁住。

4.2 next-key 退化为间隙锁

  • session A 本来的加锁范围是(5,10]
  • 但是id=10是最后一个值,且不满足条件
  • session A的加锁范围变成了(5,10), 所以session B 被阻塞,而session C没有阻塞。

4.3 一个bug

  • session A锁住的范围其实是(10,20],因为唯一索引上的范围查询,会访问到第一个不满足条件的数据为止。
  • 因此session B 和 session C会被锁住。
  • 但是正确锁的范围是(10,15]
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面试指北 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 加锁规则
    • 1. 两个原则
      • 2. 两个优化
        • 3. 一个Bug
          • 4. 举个例子
            • 4.1 next-key 退化为行锁
            • 4.2 next-key 退化为间隙锁
            • 4.3 一个bug
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档