【面试普通人VS高手系列】innoDB如何解决幻读

2024-02-08 02:10

本文主要是介绍【面试普通人VS高手系列】innoDB如何解决幻读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python微信订餐小程序课程视频

https://blog.csdn.net/m0_56069948/article/details/122285951

Python实战量化交易理财系统

https://blog.csdn.net/m0_56069948/article/details/122285941

前天有个去快手面试的小伙伴私信我,他遇到了这样一个问题: “InnoDB如何解决幻读”?

这个问题确实不是很好回答,在实际应用中,很多同学几乎都不关注数据库的事务隔离性。

所有问题基本就是CRUD,一把梭~

那么今天,我们来看一下 关于“InnoDB如何解决幻读”这个问题,普通人和高手的回答!

普通人:

嗯,我印象中,幻读是通过MVCC机制来解决的,嗯…

MVCC类似于一种乐观锁的机制,通过版本的方式来区分不同的并发事务,避免幻读问题!

高手:

我会从三个方面来回答:

1、 Mysql的事务隔离级别

Mysql有四种事务隔离级别,这四种隔离级别代表当存在多个事务并发冲突时,可能出现的脏读、不可重复读、幻读的问题。

其中InnoDB在RR的隔离级别下,解决了幻读的问题。

img

2、 什么是幻读?

那么, 什么是幻读呢?

幻读是指在同一个事务中,前后两次查询相同的范围时,得到的结果不一致

img

  • 第一个事务里面我们执行了一个范围查询,这个时候满足条件的数据只有一条
  • 第二个事务里面,它插入了一行数据,并且提交了
  • 接着第一个事务再去查询的时候,得到的结果比第一次查询的结果多出来了一条数据。

所以,幻读会带来数据一致性问题。

3、 InnoDB如何解决幻读的问题

InnoDB引入了间隙锁和next-key Lock机制来解决幻读问题,为了更清晰的说明这两种锁,我举一个例子:

假设现在存在这样一个B+ Tree的索引结构,这个结构中有四个索引元素分别是:1、4、7、10。

img

当我们通过主键索引查询一条记录,并且对这条记录通过for update加锁。

img

这个时候,会产生一个记录锁,也就是行锁,锁定id=1这个索引。

img

被锁定的记录在锁释放之前,其他事务无法对这条记录做任何操作。

前面我说过对幻读的定义: 幻读是指在同一个事务中,前后两次查询相同的范围时,得到的结果不一致!

注意,这里强调的是范围查询,

也就是说,InnoDB引擎要解决幻读问题,必须要保证一个点,就是如果一个事务通过这样一条语句进行锁定时。

img

另外一个事务再执行这样一条insert语句,需要被阻塞,直到前面获得锁的事务释放。

img

所以,在InnoDB中设计了一种间隙锁,它的主要功能是锁定一段范围内的索引记录

img

当对查询范围id>4 and id <7加锁的时候,会针对B+树中(4,7)这个开区间范围的索引加间隙锁。

意味着在这种情况下,其他事务对这个区间的数据进行插入、更新、删除都会被锁住。

但是,还有另外一种情况,比如像这样

img

这条查询语句是针对id>4这个条件加锁,那么它需要锁定多个索引区间,所以在这种情况下InnoDB引入了next-key Lock机制。

next-key Lock相当于间隙锁和记录锁的合集,记录锁锁定存在的记录行,间隙锁锁住记录行之间的间隙,而next-key Lock锁住的是两者之和。

img

每个数据行上的非唯一索引列上都会存在一把next-key lock,当某个事务持有该数据行的next-key lock时,会锁住一段左开右闭区间的数据。

因此,当通过id>4这样一种范围查询加锁时,会加next-key Lock,锁定的区间范围是:(4, 7] , (7,10],(10,+∞]

img

间隙锁和next-key Lock的区别在于加锁的范围,间隙锁只锁定两个索引之间的引用间隙,而next-key Lock会锁定多个索引区间,它包含记录锁和间隙锁。

当我们使用了范围查询,不仅仅命中了Record记录,还包含了Gap间隙,在这种情况下我们使用的就是临键锁,它是MySQL里面默认的行锁算法。

4 、总结

虽然InnoDB中通过间隙锁的方式解决了幻读问题,但是加锁之后一定会影响到并发性能,因此,如果对性能要求较高的业务场景中,可以把隔离级别设置成RC,这个级别中不存在间隙锁。

以上就是我对于innoDB如何解决幻读问题的理解!

总结:

通过这个面试题可以发现,大厂面试对于基本功的考察还是比较严格的。

不过,不管是为了应付面试,还是为以后的职业规划做铺垫, 技术能力的高低都是你在这个行业的核心竞争力。

我是Mic,一个工作了14年的Java程序员,咱们下篇文章再见。

这篇关于【面试普通人VS高手系列】innoDB如何解决幻读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/689626

相关文章

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

MySQ中出现幻读问题的解决过程

《MySQ中出现幻读问题的解决过程》文章解析MySQLInnoDB通过MVCC与间隙锁机制在可重复读隔离级别下解决幻读,确保事务一致性,同时指出性能影响及乐观锁等替代方案,帮助开发者优化数据库应用... 目录一、幻读的准确定义与核心特征幻读 vs 不可重复读二、mysql隔离级别深度解析各隔离级别的实现差异

Java报错:org.springframework.beans.factory.BeanCreationException的五种解决方法

《Java报错:org.springframework.beans.factory.BeanCreationException的五种解决方法》本文解析Spring框架中BeanCreationExce... 目录引言一、问题描述1.1 报错示例假设我们有一个简单的Java类,代表一个用户信息的实体类:然后,

MySQL磁盘空间不足问题解决

《MySQL磁盘空间不足问题解决》本文介绍查看空间使用情况的方式,以及各种空间问题的原因和解决方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录查看空间使用情况Binlog日志文件占用过多表上的索引太多导致空间不足大字段导致空间不足表空间碎片太多导致空间不足临时表空间

Mybatis-Plus 3.5.12 分页拦截器消失的问题及快速解决方法

《Mybatis-Plus3.5.12分页拦截器消失的问题及快速解决方法》作为Java开发者,我们都爱用Mybatis-Plus简化CRUD操作,尤其是它的分页功能,几行代码就能搞定复杂的分页查询... 目录一、问题场景:分页拦截器突然 “失踪”二、问题根源:依赖拆分惹的祸三、解决办法:添加扩展依赖四、分页