面试基础---MySQL 事务隔离级别与 MVCC 深度解析
MySQL 事务隔离级别与 MVCC 深度解析:原理、实践与源码分析
引言
在高并发的互联网应用中,数据库事务的隔离级别是保证数据一致性和并发性能的关键。MySQL 通过多版本并发控制(MVCC)机制实现了不同的事务隔离级别。本文将深入探讨 MySQL 的事务隔离级别和 MVCC 机制,结合实际项目案例和源码分析,帮助读者深入理解其实现原理。
1. 事务隔离级别概述
事务隔离级别定义了事务之间的可见性规则。MySQL 支持以下四种隔离级别:
- 读未提交(Read Uncommitted):事务可以读取其他事务未提交的数据。
- 读已提交(Read Committed):事务只能读取其他事务已提交的数据。
- 可重复读(Repeatable Read):事务在执行期间看到的数据保持一致,即使其他事务修改了数据。
- 串行化(Serializable):事务串行执行,完全隔离。
1.1 隔离级别与并发问题
| 隔离级别 | 脏读(Dirty Read) | 不可重复读(Non-Repeatable Read) | 幻读(Phantom Read) |
|---|---|---|---|
| 读未提交 | 可能 | 可能 | 可能 |
| 读已提交 | 不可能 | 可能 | 可能 |
| 可重复读 | 不可能 | 不可能 | 可能 |
| 串行化 | 不可能 | 不可能 | 不可能 |
2. MVCC 机制
MVCC(Multi-Version Concurrency Control)是 MySQL 实现事务隔离级别的核心技术。MVCC 通过为每条记录维护多个版本来实现并发控制。
2.1 MVCC 的核心概念
- 版本链:每条记录都有一个版本链,记录其历史版本。
- ReadView:事务在执行时创建一个 ReadView,用于判断哪些版本对当前事务可见。
- Undo Log:用于存储记录的历史版本,支持回滚和版本链的构建。
2.2 MVCC 的工作流程
2.3 MVCC 的可见性判断
MVCC 通过以下规则判断记录的可见性:
- 如果记录的创建版本号大于当前事务的 ReadView,则不可见。
- 如果记录的删除版本号小于当前事务的 ReadView,则不可见。
- 否则,记录对当前事务可见。
3. MySQL 中的事务隔离级别实现
3.1 读未提交(Read Uncommitted)
在读未提交隔离级别下,事务可以读取其他事务未提交的数据。MySQL 通过直接读取最新版本的数据实现。
3.2 读已提交(Read Committed)
在读已提交隔离级别下,事务只能读取其他事务已提交的数据。MySQL 通过为每个查询创建一个新的 ReadView 实现。
3.3 可重复读(Repeatable Read)
在可重复读隔离级别下,事务在执行期间看到的数据保持一致。MySQL 通过在事务开始时创建一个 ReadView,并在事务期间复用该 ReadView 实现。
3.4 串行化(Serializable)
在串行化隔离级别下,事务串行执行,完全隔离。MySQL 通过加锁机制实现。
4. MVCC 的源码分析
MySQL 的 MVCC 实现主要位于 storage/innobase 目录下。以下是 MVCC 的核心数据结构:
- ReadView:用于判断记录的可见性。
- Undo Log:用于存储记录的历史版本。
- trx0sys.cc:事务系统的实现,负责管理事务和 ReadView。
// ReadView 源码片段
class ReadView {
public:trx_id_t m_low_limit_id; // 低水位线,小于该值的事务可见trx_id_t m_up_limit_id; // 高水位线,大于该值的事务不可见trx_id_t m_creator_trx_id; // 创建该 ReadView 的事务 IDids_t m_ids; // 活跃事务列表bool changes_visible(trx_id_t id) const {if (id < m_up_limit_id || id == m_creator_trx_id) {return true;}if (id >= m_low_limit_id) {return false;}return !m_ids.contains(id);}
};
5. 实际项目案例
5.1 项目背景
在一个电商平台的订单系统中,订单表 orders 包含以下字段:
order_id:主键,自增。user_id:用户 ID。order_date:订单日期。amount:订单金额。
为了提高并发性能,我们需要选择合适的隔离级别。
5.2 隔离级别的选择
- 读未提交:不适合电商系统,因为可能读取到未提交的脏数据。
- 读已提交:适合大多数场景,但可能出现不可重复读问题。
- 可重复读:适合需要事务一致性的场景,如订单支付。
- 串行化:适合对一致性要求极高的场景,但性能较差。
5.3 事务示例
假设我们需要查询某个用户的订单总金额,并在事务期间保持一致性:
START TRANSACTION;
SELECT SUM(amount) FROM orders WHERE user_id = 123;
-- 其他操作
COMMIT;
在可重复读隔离级别下,即使其他事务修改了 orders 表,当前事务看到的订单总金额保持一致。
5.4 事务的性能分析
通过 EXPLAIN 命令可以分析查询的执行计划:
EXPLAIN SELECT SUM(amount) FROM orders WHERE user_id = 123;
输出结果如下:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | orders | ref | idx_user_id | idx_user_id | 4 | const | 100 | Using where |
从执行计划可以看出,MySQL 使用了 idx_user_id 索引来查找数据,保证了查询的高效性。
6. 总结
MySQL 通过 MVCC 机制实现了不同的事务隔离级别,保证了数据的一致性和并发性能。通过深入理解 MVCC 的原理及其在 MySQL 中的实现,我们可以更好地设计和优化数据库事务。
在实际项目中,合理选择事务隔离级别,结合索引和查询优化,可以显著提高系统性能。通过源码分析,我们进一步了解了 MySQL 如何通过 MVCC 实现高效的事务管理。
希望本文能为你在实际项目中优化 MySQL 事务提供帮助。
参考文献:
- MySQL 官方文档
- InnoDB 存储引擎源码
相关文章:
面试基础---MySQL 事务隔离级别与 MVCC 深度解析
MySQL 事务隔离级别与 MVCC 深度解析:原理、实践与源码分析 引言 在高并发的互联网应用中,数据库事务的隔离级别是保证数据一致性和并发性能的关键。MySQL 通过多版本并发控制(MVCC)机制实现了不同的事务隔离级别。本文将深入探…...
第十二届蓝桥杯大学A组java省赛答案整理
货物摆放 题目描述 小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 nn 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所…...
浅浅初识AI、AI大模型、AGI
前记:这里只是简单了解,后面有时间会专门来扩展和深入。 当前,人工智能(AI)及其细分领域(如AI算法工程师、自然语言处理NLP、通用人工智能AGI)的就业前景呈现高速增长态势,市场需求…...
flink集成tidb cdc
Flink TiDB CDC 详解 1. TiDB CDC 简介 1.1 TiDB CDC 的核心概念 TiDB CDC 是 TiDB 提供的变更数据捕获工具,能够实时捕获 TiDB 集群中的数据变更(如 INSERT、UPDATE、DELETE 操作),并将这些变更以事件流的形式输出。TiDB CDC 的…...
【flutter】TextField输入框工具栏文本为英文解决(不用安装插件版本
输入框长按选项菜单复制、粘贴、剪切、全选部分默认为英文,对于只需要对此部分做中文本地化,不需要考虑其他语言及全局本地化的项目,可以直接自定义一个本地化代理方法进行覆盖,不需要额外下载插件 // 自定义本地化代理 class _C…...
推荐1款OCR的扫描仪软件,无需安装,打开即用!
聊一聊 现在日常办公,很多时候还是需要扫描仪配合。 很多时候需要将文件搜索成PDF再传输。 今天给大家分享一款OCR扫描仪软件。 软件介绍 OCR的扫描仪软件 支持扫描仪共享。 支持WIA、TWAIN、SANE和ESCL驱动程序。 还可以批量多扫描仪配置扫描,支持…...
SpringBoot为什么默认使用CGLIB?
大家好,我是锋哥。今天分享关于【SpringBoot为什么默认使用CGLIB?】面试题。希望对大家有帮助; SpringBoot为什么默认使用CGLIB? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Boot 默认使用 CGLIB(Code Generation Li…...
去除HTML有序列表(ol)编号的多种解决方案
以下是去除HTML有序列表(ol)编号的多种解决方案: <!DOCTYPE html> <html> <head> <style> /* 基础方案:完全移除编号 */ ol.no-number {list-style-type: none; /* 移除默认编号 */padding-left: 0; /* 移除默认缩进 */…...
神经网络|(十三)|SOM神经网络
【1】引言 前序已经对神经网络有了基础认识,今天先学习SOM神经网络。 前序学习文章链接包括且不限于: 神经网络|(十一)|神经元和神经网络-CSDN博客 神经网络|(十二)|常见激活函数-CSDN博客 【2】SOM神经网络 SOM神经网络是一种结构比较简单、但是理…...
IP协议、DNS协议、DHCP协议、Telent协议的记忆总结
首先记忆一下几个协议的端口号 HTTP:超文本传输协议 80 HTTPS:安全传输协议 443 DHCP:动态主机配置协议 67/68 DNS:域名解析协议 53 FTP:文件传输协议 20/21 TFTP:简单文件传输协议 69 TELENT:远…...
Pico 4 Enterprise(企业版)与Unity的交互-有线串流调试篇
入手了Pico 4 E做VR开发,谁知入了天坑...根据官方文档,尝试了串流助手、企业串流、PICO Developer Center,陷入了各种版本问题、环境问题的陷阱。而且Pico4E的OS自24年12开始就不再更新,头盔中预装的企业串流版本也较低࿰…...
DeepSeek-R1:使用KTransformers实现高效部署指南
KTransformers作为一个开源框架,专门为优化大规模语言模型的推理过程而设计。它支持GPU/CPU异构计算,并针对MoE架构的稀疏性进行了特别优化,可以有效降低硬件要求,允许用户在有限的资源下运行像DeepSeek-R1这样庞大的模型。 硬件…...
企业日常工作中常用的 Linux 操作系统命令整理
Linux 操作系统命令整理 在企业级运维、开发和日常工作中,Linux 命令是绕不开的核心技能。不论是日志排查、进程管理,还是高效运维优化,掌握这些命令都能让你事半功倍!本篇文章整理了自己在日常工作中积累最常用的 Linux 命令&am…...
任务9:交换机基础及配置
CSDN 原创主页:不羁https://blog.csdn.net/2303_76492156?typeblog 一、交换机基础 交换机的概念:交换机是一种网络设备,用于连接多台计算机或网络设备,实现数据包在局域网内的快速交换。交换机基于MAC地址来转发数据包&#x…...
Notepad++ 8.6.7 安装与配置全攻略(Windows平台)
一、软件定位与核心优势 Notepad 是开源免费的代码/文本编辑器,支持超过80种编程语言的高亮显示,相比系统自带记事本具有以下优势: 轻量高效:启动速度比同类软件快30%插件扩展:支持NppExec、JSON Viewer等200插件跨文…...
SpringMVC请求处理流程:DispatcherServlet工作原理
文章目录 引言一、DispatcherServlet概述二、DispatcherServlet初始化过程三、请求接收与处理器匹配四、请求参数绑定与处理器执行五、视图解析与渲染六、异常处理机制总结 引言 SpringMVC框架是Java Web开发中最流行的MVC框架之一,其核心组件DispatcherServlet作为…...
YOLOv8目标检测推理流程及C++代码
这部分主要是使用c++对Onnx模型进行推理,边先贴代码,过段时间再详细补充下代码说明。 代码主要分成三部分,1.main_det.cpp推理函数主入口;2.inference_det.h 头文件及inference_det.cpp具体函数实现;3.CMakeList.txt. 1.main_det 推理配置信息全部写在config.txt中,执行…...
解锁数据潜能,永洪科技以数据之力简化中粮可口可乐决策之路
企业数字化转型是指企业利用数字技术和信息通信技术来改变自身的商业模式、流程和增值服务,以提高企业的竞争力和创新能力。数字化转型已经成为企业发展的重要战略,尤其在当前信息技术高速发展的时代。数字化转型还涉及到企业与消费者之间的互动和沟通。…...
Redis3 Hash 类型命令详解
1. 什么是 Redis Hash? Redis Hash 是一种 键值对集合,类似于 Java 里的 HashMap,可以用来存储对象的数据。例如,你可以将用户信息存储在 Redis 的 Hash 结构中,每个字段代表用户的一个属性。 示例: HSE…...
双链路提升网络传输的可靠性扩展可用带宽
为了提升网络传输的可靠性或增加网络可用带宽, 通常使用双链路冗余备份或者双链路聚合的方式。 本文介绍几种双链路网络通信的案例。 5GWiFi冗余传输 双Socket绑定不同网络接口:通过Android的ConnectivityManager绑定5G蜂窝网络和WiFi的Socket连接&…...
深入浅出:UniApp 从入门到精通全指南
https://juejin.cn/post/7440119937644101684 uni-app官网 uniapp安卓离线打包流程_uniapp离线打包-CSDN博客 本文是关于 UniApp 从入门到精通的全指南,涵盖基础入门(环境搭建、创建项目、项目结构、编写运行)、核心概念与进阶知识&#x…...
MDM 如何彻底改变医疗设备的远程管理
在现代医疗行业迅速发展的格局中,医院和诊所越来越依赖诸如医疗平板和移动工作站等移动设备。这些设备在提高工作效率和提供卓越的患者护理方面发挥着关键作用。然而,随着它们的广泛使用,也带来了一系列挑战,例如在不同地点确保数…...
前端性能优化之同时插入100000个元素页面不卡顿
面试官:同时插入100000个元素怎么让页面不卡顿 优化前写法 首先我们来看下面的一段,点击按钮后,循环100000次,每次都插入一个元素,并且插入区域上方还有一个小球在滚动,在插入的过程中我们可以观察小球的…...
PHP之Cookie和Session
在你有别的编程语言的基础下,你想学习PHP,可能要了解的一些关于cookie和session的信息。 Cookie 参数信息 setcookie(name,value,expire, path, domain); name : Cookie的名称。 value : Cookie的值。 expire : Cookie的过期时间,可以是一…...
vscode 配置debug的环境
vscode配置debug的环境 配置好python解释器, ctrl shift P 就可以指定python了。 当前环境下建立 .vscode 文件夹新建 .vscode/launch.json 文件文件的配置如下 {"version": "0.2.0","configurations": [{"name": &qu…...
socket基础学习以及java搭建
在 Java 中,Socket 编程用于实现网络通信。Java 提供了丰富的网络 API,使得通过 Socket 进行通信变得简单和高效。Java 的 Socket 编程常见于客户端-服务器应用中,比如聊天程序、文件传输工具等。 1. Socket 基本概念 Socket 编程的基本概念…...
Exoplayer2源码编译FFmpeg拓展模块实现音频软解码
在前面文章最新版本Exoplayer扩展FFmpeg音频软解码保姆级教程中介绍了最新版本的Exoplayer(androidx.Media3)编译FFmpeg模块的流程,有就是media3版本的explayer最低支持的sdk版本是21也就是Android5.x,但是市面上还是有很多IOT设备是很老的android4.4(sdk19)的&…...
Docker安装嵌入框架Text Embeddings Inference (TEI)
Docker安装Text Embeddings Inference (TEI) 1 简单介绍 文本嵌入推理(TEI,Text Embeddings Inference )是HuggingFace研发的一个用于部署和服务开源文本嵌入和序列分类模型的工具包。TEI兼容OpenAI的嵌入模型的规范。 # 官网地址 https:/…...
使用easyocr、PyPDF2对图像及PDF文档进行识别
一、概述 本 Python 脚本的主要功能是对当前目录及其子目录下的图片和 PDF 文件进行光学字符识别(OCR)处理。它使用 easyocr 库处理图片中的文字,使用 PyPDF2 库提取 PDF 文件中的文本,并将处理结果保存为文本文件。同时ÿ…...
MAUI(C#)安卓开发起步
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
