欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

[mysql学习笔记]

时间:2023-06-19

三种行锁算法

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 插入将会被阻塞,由此避免了幻读问题。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。