RR有幻读问题吗?MVCC能否解决幻读?
幻读是 MySQL 中一个非常普遍,且面试中经常被问到的问题,如果你还搞不懂什么是幻读?什么是 MVCC?以及 MySQL 中的锁?那么请好好收藏和阅读本篇文章,因为它非常重要。
RR 隔离级别
在 MySQL 中,RR 代表 Repeatable Read(可重复读),是数据库事务隔离级别中的一种,它的特性是保证同一个事务中,多次读取同一条记录时,读取到的数据都是一致的。它也是 MySQL 默认的事务隔离级别。
隔离级别是数据库管理系统为了处理并发访问时,控制事务之间相互影响的程度而定义的一组规则。
MVCC
MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种并发控制机制,用于在数据库系统中处理并发读写操作时保持数据的一致性和隔离性(主要是用来解决幻读问题的)。MVCC 通过在每个数据行上保存多个版本的数据来实现并发读取和写入的一致性。
MVCC 的核心思想是将每个事务的读操作与写操作解耦,通过保存数据的历史版本来实现并发控制。每个事务在开始时会创建一个读视图(Read View),用于确定在事务开始时可见的数据版本。读视图包含一个事务开始时的系统版本号,用于与数据行的版本号进行比较,以确定数据行是否对事务可见。
在 MVCC 中,当一个事务执行写操作时,会生成一个新的数据版本,并将旧版本的数据保存在回滚日志(Undo Log)中。这样,其他事务在读取数据时仍然可以访问到旧版本的数据,从而避免了幻读问题。
MVCC 工作流程如下:
- 读操作:当一个事务执行 SELECT 语句时,会根据读视图的系统版本号和数据行的版本号进行比较,只读取在事务开始之前已经提交的数据行。这样,即使其他事务正在并发地插入或删除数据,事务仍然可以读取到一致的数据。
- 写操作:当一个事务执行 INSERT、UPDATE 或 DELETE 语句时,会生成新的数据版本,并将旧版本的数据保存在回滚日志中。这样,其他事务在读取数据时仍然可以访问到旧版本的数据,从而避免了幻读问题。
MVCC 机制在数据库系统中广泛应用,特别是在支持事务的存储引擎中,如 MySQL 的 InnoDB 引擎。它通过解耦读操作和写操作,提供了高并发性能和数据一致性,使得多个事务可以同时读取和修改数据库,而不会相互干扰。
RR + MVCC 有幻读问题吗?
在 MySQL 中,即使是RR 隔离级别(可重复读),虽然它通过 MVCC 消除了绝大部分幻读问题,但依旧存在部分幻读问题,所以 RR 隔离级别存在幻读问题,而 MVCC 也没有彻底解决幻读问题。
幻读问题演示
在 RR 隔离级别中存在两种读操作:
- 快照读:数据库中一种读取数据的方式,它基于事务开始时的一个一致性快照来读取数据。快照读可以提供事务开始时的数据视图,即使在事务执行期间其他事务对数据进行了修改,也不会影响快照读取到的数据。简单理解,快照读就是事务开启时创建一个缓存,之后的查询都会从这个缓存中获取数据。
- 当前读:数据库中一种读取数据的方式,它读取最新提交的数据,而不是基于事务开始时的一致性快照。
所以,在 RR 隔离级别中 MVCC 通过快照读的方式解决了大部分幻读问题,但如果 RR 隔离级别存在当前读(使用 select ... for update 实现),那么此时也会发生幻读问题,比如以下执行过程:

如何彻底解决幻读?
想要彻底解决幻读问题,有两个方案:
- 使用串行化(Serializable)隔离级别:官方推荐方案,但这种解决方案,并发性能比较低。
- RR + 锁:使用 RR 隔离级别,但在事务开启之后立即加锁,如下图所示:
事务一开启之后就加锁,之后其他事务在操作此表的相关数据时,就只能等待锁释放(事务一提交或回滚锁自动释放)。
小结
在可重复读级别中,MySQL 虽然使用 MVCC 解决了大部分幻读问题,但在当前读的操作中依然有幻读问题,此时可以通过加锁,或升级隔离级别为串行化来解决幻读问题。
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。
RR有幻读问题吗?MVCC能否解决幻读?的更多相关文章
- MVCC 能解决幻读吗?
MySQL通过MVCC(解决读写并发问题)和间隙锁(解决写写并发问题)来解决幻读 MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ). 未提交读(REA ...
- MySQL锁(三)行锁:幻读是什么?如何解决幻读?
概述 前面两篇文章介绍了MySQL的全局锁和表级锁,今天就介绍一下MySQL的行锁. MySQL的行锁是各个引擎内部实现的,不是所有的引擎支持行锁,例如MyISAM就不支持行锁. 不支持行锁就意味着在 ...
- MySQL 是如何解决幻读的
MySQL 是如何解决幻读的 一.什么是幻读 在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读. 而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证 ...
- 何为幻读?MySQL又是如何解决幻读的?
一.什么是幻读 在一次事务里面,多次查询之后,查询的结果集的个数不一致的情况叫做幻读.而多出来或者少的哪一行被叫做 幻行 二.为什么要解决幻读 在高并发数据库系统中,需要保证事务与事务之间的隔离性,还 ...
- 【大厂面试03期】MySQL是怎么解决幻读问题的?
问题分析 首先幻读是什么? 根据MySQL文档上面的定义 The so-called phantom problem occurs within a transaction when the same ...
- MySQL到底能否解决幻读问题
先说结论,MySQL 存储引擎 InnoDB 在可重复读(RR)隔离级别下是解决了幻读问题的. 方法:是通过next-key lock在当前读事务开启时,1.给涉及到的行加写锁(行锁)防止写操作:2. ...
- InnoDB 是如何解决幻读的
前言 大部分人在日常的业务开发中,其实很少去关注数据库的事务相关问题,基本上都是 CURD 一把梭.正好最近在看 MySQL 的相关基础知识,其中对于幻读问题之前一直没有理解深刻,今天就来聊聊「Inn ...
- InnoDB解决幻读的方案——LBCC&MVCC
最近要在公司内做一次技术分享,思来想去不知道该分享些什么,最后在朋友的提示下,准备分享一下MySQL的InnoDB引擎下的事务幻读问题与解决方案--LBCC&MVCC.经过好几天的熬夜通宵,终 ...
- MySQL的可重复读级别能解决幻读吗
引言 之前在深入了解数据库理论的时候,了解到事物的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了.但是对于幻 ...
- MySQL 到底是怎么解决幻读的?
; 原理:将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的. 2. next-key 锁 (当前读) next-key 锁包含两部分: 记录锁(行锁) 间隙锁 记录锁是加在 ...
随机推荐
- 2022-09-03:n块石头放置在二维平面中的一些整数坐标点上 每个坐标点上最多只能有一块石头 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。 给你一个长度为 n 的数组
2022-09-03:n块石头放置在二维平面中的一些整数坐标点上 每个坐标点上最多只能有一块石头 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头. 给你一个长度为 n 的数组 ...
- 2020-12-29:mysql中,innodb表里,某一条数据删除了之后,这条数据会被真实的擦掉吗,还是删除了关系?
福哥答案2020-12-29:[答案来自此链接,答案相当详细:](https://www.zhihu.com/question/436957843)面试的时候受 <MySQL技术内幕 InnoD ...
- vue全家桶进阶之路13:生命周期
Vue2的生命周期是指Vue实例从创建.挂载.更新.销毁等各个阶段中所经历的一系列过程.Vue2的生命周期共有8个阶段,分别是: beforeCreate:Vue实例被创建之前的阶段,此时Vue实例的 ...
- Tensorflow 2下载网址
Tensorflow2: 官网:https://tensorflow.google.cn/ 一个核心开源库,可以帮助您开发和训练机器学习模型.您可以通过直接在浏览器中运行 Colab 笔记本来快速上手 ...
- Odoo-----计算字段、depnds,onchange 机制、模型约束
1 计算字段和默认值问题 字段通过调用模型的方法的实时计算获得,一般都是 compute 属性为主的方法,这个计算方法通过计算self每条记录设置的的值,self 是一个有记录的有序集合,支持py ...
- Docker-Compose快速搭建LNMP
Docker-Compose 1.安装Docker sudo apt -y install docker.io docker version 查看版本号 docker help 查看帮助文档 2.更换 ...
- Java(命令行传参、可变参数、递归
1.命令行传参 通过命令行传参,main也可以传参 public class Hello { public static void main(String[] args) { for (int i = ...
- R 语言中常见的 10 个错误,看到第 7 个会不会感觉很神奇?
翻译:BioIT 爱好者(部分内容有调整)原文:The top 10 R errors, the 7th one will surprise you 就像你学习走路时遇到了一些问题,你在学习 R 的过 ...
- R 包初学者指南
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 基于 11 个最常见的用户问题介绍 R 软件包. R 包是由社区开发 (developed b ...
- 【HarmonyOS】如何获取公共目录的图片等文件(API7 FA模型JS语言)
[关键字] API7.JS.公共目录.@ohos.multimedia.mediaLibrary [前言] 在使用API7 JS开发HarmonyOS应用时,需要获取非应用目录即内部存储公共目录下 ...