当前位置: 首页 > news >正文

java八股文面试[数据库]——可重复读怎么实现的(MVCC)

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

MVCC
  • MVCC,多版本并发控制, 用于实现读已提交可重复读隔离级别。

  • MVCC的核心就是 Undo log多版本链 + Read view,“MV”就是通过 Undo log来保存数据的历史版本,实现多版本的管理,“CC”是通过 Read-view来实现管理,通过 Read-view原则来决定数据是否显示。同时针对不同的隔离级别, Read view的生成策略不同,也就实现了不同的隔离级别。

Undo log 多版本链

每条数据都有两个隐藏字段:

  • trx_id: 事务id,记录最近一次更新这条数据的事务id.

  • roll_pointer: 回滚指针,指向之前生成的undo log

image.png

每一条数据都有多个版本,版本之间通过undo log链条进行连接通过这样的设计方式,可以保证每个事务提交的时候,一旦需要回滚操作,可以保证同一个事务只能读取到比当前版本更早提交的值,不能看到更晚提交的值。

ReadView

Read View是 InnoDB 在实现 MVCC 时用到的一致性读视图,即 consistent read view,用于支持 RC(Read Committed,读提交)和 RR(Repeatable Read,可重复读)隔离级别的实现.

Read View简单理解就是对数据在某个时刻的状态拍成照片记录下来。那么之后获取某时刻的数据时就还是原来的照片上的数据,是不会变的.

Read View中比较重要的字段有4个:

  • m_ids : 用来表示MySQL中哪些事务正在执行,但是没有提交.

  • min_trx_id: 就是m_ids里最小的值.

  • max_trx_id : 下一个要生成的事务id值,也就是最大事务id

  • creator_trx_id: 就是你这个事务的id

image.png

当一个事务第一次执行查询sql时,会生成一致性视图 read-view(快照),查询时从 undo log 中最新的一条记录开始跟 read-view 做对比,如果不符合比较规则,就根据回滚指针回滚到上一条记录继续比较,直到得到符合比较条件的查询结果。

Read View判断记录某个版本是否可见的规则如下

image.png

1.如果当前记录的事务id落在绿色部分(trx_id < min_id),表示这个版本是已提交的事务生成的,可读。 2.如果当前记录的事务id落在红色部分(trx_id > max_id),表示这个版本是由将来启动的事务生成的,不可读。

  1. 如果当前记录的事务id落在黄色部分(min_id <= trx_id <= max_id),则分为两种情况:

  2. 若当前记录的事务id在未提交事务的数组中,则此条记录不可读;

  3. 若当前记录的事务id不在未提交事务的数组中,则此条记录可读。

RC 和 RR 隔离级别都是由 MVCC 实现,区别在于

  • RC 隔离级别时,read-view 是每次执行 select 语句时都生成一个

  • RR 隔离级别时,read-view 是在第一次执行 select 语句时生成一个,同一事务中后面的所有 select 语句都复用这个 read-view

Repeatable Read 解决了幻读问题吗?

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

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

注意在可重复读隔离级别下,普通的查询快照读,是不会看到别的事务插入的数据的。因此, 幻读在“当前读”下才会出现(查询语句添加for update,表示当前读);

在 MVCC 并发控制中,读操作可以分为两类: 快照读(Snapshot Read)与当前读 (Current Read)。

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

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

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

  • 当前读 当前读是读取的数据库最新的数据,当前读和快照读不同,因为要读取最新的数据而且要保证事务的隔离性,所以当前读是需要对数据进行加锁的(插入/更新/删除操作,属于当前读,需要加锁 , select for update 为当前读)

表结构

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这一样的现象,就称之为幻读,幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行

先对“幻读”做出如下解释:

  • 要讨论「可重复读」隔离级别的幻读现象,是要建立在「当前读」的情况下,而不是快照读,因为在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。

Next-key Lock 锁

产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题,就引出了 next-key 锁,就是记录锁和间隙锁的组合

  • RecordLock锁:锁定单个行记录的锁。(记录锁,RC、RR隔离级别都支持)

  • GapLock锁:间隙锁,锁定索引记录间隙(不包括记录本身),确保索引记录的间隙不变。(范围锁,RR隔离级别支持)

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

image.png

总结

  • RR隔离级别下间隙锁才有效,RC隔离级别下没有间隙锁;

  • RR隔离级别下为了解决“幻读”问题:“快照读”依靠MVCC控制,“当前读”通过间隙锁解决

  • 间隙锁和行锁合称next-key lock,每个next-key lock是前开后闭区间;

  • 间隙锁的引入,可能会导致同样语句锁住更大的范围影响并发度

知识来源:马士兵教育

相关文章:

java八股文面试[数据库]——可重复读怎么实现的(MVCC)

可重复读&#xff08;repeatable read&#xff09;定义&#xff1a; 一个事务执行过程中看到的数据&#xff0c;总是跟这个事务在启动时看到的数据是一致的。 MVCC MVCC&#xff0c;多版本并发控制, 用于实现读已提交和可重复读隔离级别。 MVCC的核心就是 Undo log多版本链 …...

cl 和 “clangtidy“分别是什么?是同一样东西吗?

作者&#xff1a;gentle_zhou 原文链接&#xff1a;cl 和 "clangtidy"分别是什么&#xff1f;是同一样东西吗&#xff1f;-云社区-华为云 先说结论&#xff1a;这两个是不同的工具&#xff0c;cl是编译器&#xff0c;clangtidy是代码检查工具&#xff0c;它们不是一…...

ubuntu22.04开机自启动Eureka服务

ubuntu22.04开机自启动Eureka服务 1、创建启动脚本eurekaService.sh #我们把启动脚本放在/usr/software目录下 cd /usr/software vim eurekaService.sheurekaService.sh内容为 #!/bin/sh # this is a eurekaService shell to startup at the mechian power on.echo "eu…...

【 OpenGauss源码学习 —— 列存储(analyze)(三)】

列存储&#xff08;analyze&#xff09; acquire_sample_rows 函数RelationGetNumberOfBlocks 函数BlockSampler_Init 函数anl_init_selection_state 函数BlockSampler_GetBlock 函数ReadBufferExtendedPageGetMaxOffsetNumber 函数HeapTupleSatisfiesVacuum 函数heapCopyTuple…...

Element Plus table formatter函数返回html内容

查看 Element Plus table formatter 支持返回 类型为string 和 VNode对象&#xff1b; 若依全局直接用h函数&#xff0c;无需引用 下面普通基本用法&#xff1a;在Element Plus中&#xff0c;你可以使用自定义的formatter函数来返回VNode对象&#xff0c;从而实现更灵活的自定…...

c++ mutable

mutable 可变的&#xff0c;易变的 跟 constant&#xff08;既C中的const&#xff09;是反义词作用&#xff1a; 保持常量对象中大部分数据成员仍然是“只读”的情况下&#xff0c;实现对个别数据成员的修改使类的const函数可以修改对象的mutable数据成员。 注意事项&#xff…...

element-plus 踩的坑

原来node版本是16.17.0,装element-plus死活装不上&#xff0c;结果要把node版本升级到18以上&#xff0c;真坑呀&#xff0c;也没人告诉我要这么干...

Python、Rust中的协程

协程 协程在不同的堆栈上同时运行&#xff0c;但每次只有一个协程运行&#xff0c;而其调用者则等待: F启动G&#xff0c;但G并不会立即运行&#xff0c;F必须显式的恢复G&#xff0c;然后 G 开始运行。在任何时候&#xff0c;G 都可能转身并让步返回到 F。这会暂停 G 并继续…...

Vuepress样式修改内容宽度

1、相关文件 一般所在目录node_modules\vuepress\theme-default\styles\wrapper.styl 2、调整宽度&#xff0c;截图中是已经调整好的&#xff0c;在我电脑上显示刚刚好。...

Vue2电商前台项目——项目的初始化及搭建

Vue2电商前台项目——项目的初始化及搭建 Vue基础知识点击此处——Vue.js 文章目录 Vue2电商前台项目——项目的初始化及搭建一、项目初始化1、脚手架目录介绍2、项目的其他配置 二、项目的路由分析及搭建1、项目的路由分析2、开发项目的步骤3、非路由组件的搭建4、路由组件的搭…...

递归算法学习——N皇后问题,单词搜索

目录 ​编辑 一&#xff0c;N皇后问题 1.题意 2.解释 3.题目接口 4.解题思路及代码 二&#xff0c;单词搜索 1.题意 2.解释 3.题目接口 4.思路及代码 一&#xff0c;N皇后问题 1.题意 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上…...

【SpringBoot】mockito+junit 单元测试

1.POM 引入以下依赖 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.springframework.b…...

webserver 同步 I/O 模拟 Proactor 模式的工作流程

服务器基本框架、I/O 模型、事件处理模式 一、服务器编程基本框架 虽然服务器程序种类繁多&#xff0c;但其基本框架都一样&#xff0c;不同之处在于逻辑处理。 二、五种 I/O 模型 阻塞/非阻塞、同步/异步&#xff08;网络IO&#xff09;_呵呵哒(&#xffe3;▽&#xffe3;)&…...

mysql8-基于docker搭建主从同步

一、环境信息 系统版本&#xff1a;CentOS Linux release 7.9.2009 (Core) cat /etc/centos-release Docker版本&#xff1a;Docker version 20.10.6, build 370c289 docker --version Docker-compose版本&#xff1a;Docker Compose version v2.10.2 docker-compose --versio…...

智能水表远程控制系统:引领节水新时代

随着科技的不断发展&#xff0c;物联网技术逐渐融入到我们的日常生活中。其中&#xff0c;智能水表远程控制系统成为一项重要创新&#xff0c;对于提高水资源利用率、实现绿色节水具有重要意义。下面小编就来为大家介绍下智能水表远程控制系统吧! 一、智能水表远程控制系统定义…...

【FusionInsight 迁移】HBase从C50迁移到6.5.1(03)6.5.1上准备Loader

【FusionInsight 迁移】HBase从C50迁移到6.5.1&#xff08;03&#xff09;6.5.1上准备Loader HBase从C50迁移到6.5.1&#xff08;03&#xff09;6.5.1上准备Loader登录新集群FusionInsight 6.5.1的Manager准备Loader服务准备Loader Role准备Loader User HBase从C50迁移到6.5.1&…...

redis多线程操作

今天更新一个redis多线程操作&#xff0c; 可直接搬运 import redis, os, threading, queue import pandas as pd# 创建一个任务队列 task_queue queue.Queue()def read_excel(folder_path):total_list []for filepath, dirnames, filenames in os.walk(folder_path):for fi…...

OpenCV(十七):拉普拉斯图像金字塔

1.拉普拉斯图像金字塔原理 拉普拉斯图像金字塔是一种多尺度图像表示方法&#xff0c;通过对高斯金字塔进行差分运算得到。它能够提供图像在不同尺度上的细节信息&#xff0c;常用于图像处理任务如图像增强、边缘检测等。 下面是拉普拉斯图像金字塔的原理和步骤&#xff1a; 构…...

OpenCL编程指南-10.2使用C++包装器API的矢量相加示例

选择OpenCL平台并创建一个上下文 建立OpenCL的第一步是选择一个平台。第2章介绍过&#xff0c;OpenCL使用了ICD模型&#xff0c;其中可以有多个OpenCL实现在一个系统上并存。类似于HelloWorld示例&#xff0c;这个矢量相加程序展示了选择OpenCL平台的一种最简单的方法&#xf…...

mysql数据库,字符串使用双引号““导致报错,使用单引号‘‘不报错,Unknown column ‘user-test‘ in ‘where clause‘

文章目录 一、完整报错二、报错数据三、报错原因四、解决方式1、更改执行sql2、更改sql数据校验模式&#xff08;改为默认校验&#xff09; 一、完整报错 > 1054 - Unknown column user-test in where clause二、报错数据 SELECT * FROM config_info WHERE config_info.da…...

终极指南:如何用Ice打造清爽Mac菜单栏?2025年最强大的macOS菜单栏管理工具

终极指南&#xff1a;如何用Ice打造清爽Mac菜单栏&#xff1f;2025年最强大的macOS菜单栏管理工具 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice是一款强大的macOS菜单栏管理工具&#xff0c;它…...

具身智能“标准线”划定,行业分化加剧?

近期具身智能行业有两件大事&#xff0c;宇树科技计划 IPO&#xff0c;首个行业标准发布。这两条“标准线”的确立&#xff0c;或使品牌和投融资市场迎来马太效应&#xff0c;推动行业分化。标准确立&#xff0c;行业分化开端具身智能行业的两件大事看似关联不大&#xff0c;实…...

YOLOv9镜像实测:无需配置环境,快速实现目标检测全流程

YOLOv9镜像实测&#xff1a;无需配置环境&#xff0c;快速实现目标检测全流程 1. 开箱即用的YOLOv9体验 对于目标检测开发者来说&#xff0c;最头疼的往往不是算法本身&#xff0c;而是环境配置这个"拦路虎"。不同版本的CUDA、PyTorch、Python之间的兼容性问题&…...

告别论文格式内耗!从标题层级到参考文献,这款工具一键搞定全流程合规排版

在学位论文撰写中&#xff0c;标题层级混乱、页眉页脚错位、参考文献格式不统一、图表排版杂乱是贯穿全文的高频痛点&#xff0c;堪称学术写作的 “格式重灾区”。传统 Word/WPS 依赖手动刷样式、调格式&#xff0c;耗时数小时还易反复出错&#xff1b;LaTeX 门槛高、中文适配差…...

从电动车痛点出发:双三相永磁电机如何靠‘弱磁’跑得更远更快?(深入对比凸极与隐极设计)

双三相永磁电机弱磁控制技术&#xff1a;破解电动车高速性能瓶颈的工程实践 电动车的高速巡航与急加速能力一直是用户关注的焦点&#xff0c;而永磁同步电机&#xff08;PMSM&#xff09;的弱磁控制技术正是解锁这一性能的关键。不同于传统三相电机&#xff0c;双三相永磁同步…...

Qwen3-VL-WEBUI效果实测:对比其他模型,看看优势在哪里

Qwen3-VL-WEBUI效果实测&#xff1a;对比其他模型&#xff0c;看看优势在哪里 1. 引言&#xff1a;当AI不仅能“看”&#xff0c;还能“做” 想象一下&#xff0c;你给AI看一张软件界面的截图&#xff0c;它不仅能告诉你界面上有什么&#xff0c;还能一步步指导你如何操作&am…...

如何快速实现Obsidian插件本地化:obsidian-i18n完整实践指南

如何快速实现Obsidian插件本地化&#xff1a;obsidian-i18n完整实践指南 【免费下载链接】obsidian-i18n 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-i18n 你是否曾因Obsidian插件全是英文界面而苦恼&#xff1f;作为中文用户&#xff0c;面对"Backli…...

3步打造跨设备开发工作站:code-server全场景部署指南

3步打造跨设备开发工作站&#xff1a;code-server全场景部署指南 【免费下载链接】code-server VS Code in the browser 项目地址: https://gitcode.com/GitHub_Trending/co/code-server 作为开发者&#xff0c;你是否曾面临设备限制带来的开发困境&#xff1f;高性能电…...

惠普暗影精灵性能优化新选择:OmenSuperHub完全解析

惠普暗影精灵性能优化新选择&#xff1a;OmenSuperHub完全解析 【免费下载链接】OmenSuperHub 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否厌倦了官方Omen Gaming Hub的臃肿体验&#xff1f;想要一个纯净、高效且完全离线的惠普暗影精灵控制工具…...

JDK 25模块路径在统信UOS/麒麟V10上启动失败?3步定位osgi-container冲突、jni.so符号缺失与jmod签名验签绕过方案

第一章&#xff1a;Java 25 模块化部署国产化适配方案Java 25 引入了更严格的模块系统约束与原生镜像增强能力&#xff0c;为在麒麟V10、统信UOS、openEuler等国产操作系统上实现轻量、安全、可验证的Java应用部署提供了新路径。适配核心聚焦于JVM层兼容性、模块图裁剪、国密算…...