MySQL间隙锁是什么

一. 写在前面的话

当下各行各业都卷到飞起,IT行业更是如此。对很多程序员来说,面试的难度、深度、广度,都让你承受着 "你这个年纪不该承受的一切"。以MySQL为例,我大学刚毕业那会,面试时也就问一下 "MySQL查询怎么去重?"、"MySQL组函数有哪些?";而现在刚毕业的学生去面试,上来就是 "聊聊MySQL的架构吧"、"你看过MySQL的源码没有?"。现在想想还真是庆幸自己毕业的早,以那时大学毕业的水平拿到现在找工作,估计得饿死。

存储(数据库存储或者内存存储)是所有系统中最最重要的一个部分,它们提供了任何系统运行所需要的所有数据,程序员几乎每日的工作都是直接或者间接地与各种存储打交道。正因如此,存储必然更是面试时的 "重灾区"。

二. MySQL间隙锁

我第一次听到MySQL的间隙锁,还是在2016年去一家公司面试的时候,整个过程还是非常愉快与顺利的。但面试那哥们儿突然问了一句, "你知道MySQL的间隙锁吗?",我脑子中迅速提取各种锁:"悲观锁"、"乐观锁"、"行锁"、"表锁"、"悲观锁"、"乐观锁"......阿xi吧,间隙锁是个什么鬼?!

然后我只能无奈地回答道:"这个我不是很清楚了",然后面试就结束了.......从那个公司出来后,我就坐的花坛边,用手机各种查,各种搜,才对间隙锁有了初步的了解,在未来几天里我就一直花时间来深入地理解间隙锁。

笔者认为,要想深入理解某个概念,必须得搞明白这个东西它出现的意义在哪里?它到底是为了解决什么问题而产生的?然后带着这些疑问去寻找答案,当谜底一层层的解开,你会觉得神清气爽,整个人都会觉得精神抖擞。

我在给大家在解答什么是间隙锁,及其能够解决什么问题之前,会先带各位捋清一些相关知识:事务的隔离级别以及快照读和当前读。

2.1 事务的隔离级别

事务的隔离级别有四种,以及每种隔离级别会产生的问题,都如下表所示:

image.png

有些人可能会问了,间隙锁与隔离级别有什么关系呢?其实间隙锁的出现,就是为了解决InnoDB存储引擎中,可重复读在当前读中产生的幻读问题!

2.2 快照读与当前读

2.2.1 快照读

在讲解快照读之前,我们先来看看笔者的一段SQL操作。

扫描二维码关注公众号,回复: 15955496 查看本文章

我们知道,MySQL的默认隔离级别是可重复读。按照红色标注的序号,并没有出现幻读问题,这是什么原因呢?这是因为MySQL通过快照读,解决了可重复读这种隔离级别情况下的幻读问题!那什么又是快照读呢?

快照读,简单点来说就是数据有很多个版本,事务在并发执行的时候,某个事务读取到的是其中一个快照。笔者再用一个可能不是很贴切但比较好理解的例子来给大家说明,就是事务或者查询开始的时候,针对要查询的数据生成一些副本,然后在后续的查询中获取的是该副本的数据。

2.2.2 当前读

当前读的意思是,查询到的永远是数据库中最新的数据,没有快照。适用如下这些语句:

  1. select ... from table_name in share mode;
  2. select ... from table_name for update;
  3. insert;
  4. update;
  5. delete

2.3 间隙锁

 2.1 事务的隔离级别 章节中我们提过,间隙锁是为了解决InnoDB存储引擎中可重复读导致的幻读问题,那么到底什么是间隙锁呢?我们先看如下的操作:

针对图中的第二条查询SQL语句:  

select * from foo where id < 10 and id > 5 for update;

笔者提出两个问题:

  1. 该SQL很明显是当前读,而当前读读取的是数据库中最新的数据。那么现在有个问题,此时如果另外有一个事务插入一条id为8的数据,再执行相同的SQL语句,是否就不会出现幻读了吗?
  2. 如果问题1的结果是没有出现幻读,肯定是通过锁机制,那么这又是如何上锁的?那么如果插入的id分别为8、12、17的数据,又会出现什么现象呢?id为12、17并不会让查询结果产生幻读吗?

针对问题一,如下图所示:

image.png

我们知道,当前读读取的是数据库中最新的数据。右侧的数据如果能提交的话,左侧的查询必然会产生幻读问题,所以会通过上锁的方式阻止事务的提交,而这个锁就是间隙锁。当你理解了问题二,我深信你一定会明白什么是间隙锁。

针对问题一,依次观察如下两张图:

出现上面两图结果的原因在于,因为 foo表中的数据id为1、4、7、9、15、18,当查询id在(5,10)之间的时候,锁的并不是整个数据库表,而是查找离下限(5)最大的id值和上限(10)最小的id值,分别为4和15;然后锁的区间范围为(4,15],也就是说处于这个区间的id是无法插入进去的,所以导致了上面两张图的结果。

现在你知道间隙锁是怎么回事了吗?如果还有不明白的,可以在评论区留言讨论哦。当然,你也可以加入到我们的学习交流群,和大家一起来互动学习哦。

猜你喜欢

转载自blog.csdn.net/GUDUzhongliang/article/details/131914624