栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

[mysql 学习笔记] - Next-key 锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[mysql 学习笔记] - Next-key 锁

三种行锁算法

InnoDB 支持行锁,包含三种行锁算法:

  • Record Lock: 单个记录上的锁;
  • Gap Lock: 间隙锁,它锁住的是一个范围,不包含记录本身;Next-key Lock: 等效于 Record Lock + Gap Lock。

    特别注意:InnoDB 行锁是通过 给索引上的索引项加锁来实现的。因此,在执行当前读的sql语句时,一定要记得带上索引条件,否则,mysql 将会执行全表扫描,将整个表锁住。

    假设有一张测试表 t:

    create table t (a int primary key);
    insert into t select 1;
    insert into t select 2;
    insert into t select 5;

    执行 select * from t for update(这里一定要使用 当前读),三种锁算法锁定的记录/范围可以表示为:

    注:∞ 不是数学意义上的无穷大,只是 mysql 定义的一个不存在的最大值。

    Next-key Lock

    InnoDB 默认的事务隔离级别是 可重复读(RR),对于行的查询都是使用的 Next-key Lock 算法,当然,为了提高并发性,在特定的查询中,Next-key Lock 可能降级为 Record Lock 或者 Gap Lock。

    实际的加锁规则是比较复杂的,而且可能因为版本的不同而有所差异,因此,这里不做深究,可以参考文章(MySQL锁详解),对加锁规则做了详细的介绍以及案例展示。再次强调,加锁规则由于版本不同而存在差异,本人机器安装 mysql 版本是 8.0.18,针对文章里第六节描述的 案例 3 和案例 6 就和本人实测结果不一致。

    解决幻读问题

    幻读指的是在同一事务下,多次执行同样的读取操作,读到的结果集不一致。而 Next-key 通过对范围加锁就可以解决这个问题。

    还是用以上测试表 t,一个事务 T1 执行如下查询:

    select * from t where a > 2 for update;

    查询会返回 5 这一条记录。

    此时,如果另一个事务 T2 想要执行插入语句: insert into t select 4,那么

    如果没有 Next-key Lock,插入语句将会成功执行,那么事务 T1 再次执行以上查询语句将会返回 4 和 5 两条记录,与第一次返回的结果集不一样,不满足可重复读的事务隔离级别。

    如果考虑 Next-key Lock,以上 sql 查询会对 (2,+∞)这个范围加锁,因此事务 T2 插入将会被阻塞,由此避免了幻读问题。

  • 转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/735404.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号