面试之可重复读是否可以解决幻读

文章介绍了可重复读隔离级别下数据库事务处理的原理,包括快照读和当前读的概念。快照读不加锁,避免了修改与读取的冲突,而当前读则需要加锁以保证数据一致性。在InnoDB存储引擎中,为解决幻读问题,引入了Next-KeyLock机制,它结合了行锁和间隙锁,防止在可重复读隔离级别下的幻读现象。
摘要由CSDN通过智能技术生成

可重复读(repeatable read)定义:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据时是一致的。

不过理论上 是会出现幻读的,简单的来说幻读指的是当用户读取某一范围的数据行时,另外一个事务又在该范围插入了新行,当用户再次读取该范围的数据时会发现 出现新的幻影行。

注意可重复读隔离级别下,普通的查询是快照读,是不会看到别的事物插入的数据的。因此,当前在”当前读“下才会出现 幻读。

在mvcc并发控制中,读操作可以分为两类:快照读 和当前读。

快照读:

快照读 :是 在读取的数据 时 不是读取最新版本的数据。而是基于历史版本读取的一个快照信息(mysql 读取 undo log 历史版本),快照读可以使用普通的select 读取时不用在对表数据 及逆行加锁,从而解决了因为数据库表的加锁而导致的两个问题

1:解决了因加锁导致的修改数据时无法对胡数据读取问题

2:解决了因加锁导致读取数据时无法对进行修改的问题。

当前读:读取的数据最新的数据,当前读和快照读不同,因为读取最新的数据而且保证事务的隔离性,所以当前读 是需要对数据进行加锁的。

下面举个列子:

表结构

idkeyvalue
000
111

假设 select * from where value=1 for update,只在这一行加锁(注意这只是假设),其它行不加锁,那么就会出现如下场景:

image.png

Session A的三次查询Q1-Q3都是select * from where value=1 for update,查询的value=1的所有row。

  • T1:Q1只返回一行(1,1,1);

  • T2:session B更新id=0的value为1,此时表t中value=1的数据有两行

  • T3:Q2返回两行(0,0,1),(1,1,1)

  • T4:session C插入一行(6,6,1),此时表t中value=1的数据有三行

  • T5:Q3返回三行(0,0,1),(1,1,1),(6,6,1)

  • T6:session A事物commit。

其中Q3读到value=1这一样的现象,就称之为幻读,幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行

产生幻读的原因是:行锁只能锁住行,但是新插入记录的这个动作,要更新的是记录之间的'间隙'。因此,Innodb 引擎 为了解决[  可重读]隔离级别下 [当前读]而造成的幻读问题,就引出了 next_key锁,就是记录锁和 间隙锁的组合。

1:RecordLock锁:锁定单个行记录的锁。

2:CapLock锁:间隙锁,锁定索引记录间隙,确保索引记录的间隙不变(范围锁,RR隔离级别支持)

3:Next-key Lock 锁: 记录时锁和间隙锁组合。锁住数据的同时,并且锁住 数据前后范围。(记录锁+范围锁,RR隔离级别支持)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值