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

MySQL 事务隔离级别与 MVCC 深度解析

引言

从并发问题出发,彻底理解 MySQL 为什么这样设计事务隔离

一、为什么需要事务隔离级别?

在并发数据库系统中,多个事务同时读写同一份数据是常态。如果不加任何控制,就会引发各种数据一致性问题,例如:

  • 一个事务读到了另一个事务尚未提交的数据
  • 同一事务中,两次查询结果不一致
  • 查询过程中“凭空多出”一些记录

这些问题统称为并发读问题,而事务隔离级别(Isolation Level),正是数据库在「性能」和「一致性」之间做出的不同权衡方案。

二、MySQL 支持的四种事务隔离级别

SQL 标准定义了四种隔离级别,MySQL(InnoDB)全部支持。

读未提交(Read Uncommitted)

特点
  • 一个事务可以读到另一个事务尚未提交的数据
问题
  • 脏读(Dirty Read)
示例
事务A:update account set balance = 0 where id = 1; (未提交) 事务B:select balance from account where id = 1; → 读到 0 事务A:rollback;

B 读到的数据是从未真正存在过的

评价
  • 几乎不加任何隔离
  • 实际生产环境基本不用

读已提交(Read Committed)

Oracle 的默认隔离级别

特点
  • 只能读到已提交的数据
  • 每次查询都会读取最新已提交版本
解决的问题
  • 避免脏读
仍然存在的问题
  • 不可重复读(Non-repeatable Read)
示例
事务A:select balance → 100 事务B:update balance = 200; commit; 事务A:select balance → 200

同一个事务中,两次读取结果不同

可重复读(Repeatable Read)⭐

MySQL InnoDB 默认隔离级别

特点
  • 同一个事务中,多次读取同一行记录结果一致
  • 基于MVCC(多版本并发控制)
能解决的问题
  • 脏读
  • 不可重复读
可重复读下,事务 A 提交的数据,事务 B 能看到吗?

分两种情况:

情况一:普通快照读(一致性读)
select * from table;
  • 看不到
  • 使用事务开始时生成的 Read View
情况二:当前读(锁定读)
select * from table for update; select * from table lock in share mode;
  • 可以看到
  • 直接读取最新版本

这正是 MySQL 可重复读与其他数据库的核心区别之一

串行化(Serializable)

特点
  • 所有事务串行执行
  • 强制加锁(行锁 / 表锁)
实现方式
  • 一种实现方式:读操作也加行级锁
  • 完全避免并发问题
缺点
  • 并发性能极差
  • 几乎不用于高并发系统

三、可重复读真的解决了幻读吗?

什么是幻读(Phantom Read)?

事务A:select count(*) from orders where price > 100; 事务B:insert into orders values (..., price=200); commit; 事务A:再次 select count(*) → 结果变多

多出“幻影行”

MySQL 的“特殊之处”

严格来说:

可重复读 + MVCC 并不能完全解决幻读

  • MVCC 只能保证已存在记录的版本一致
  • 对于新插入的记录,MVCC 无能为力

MySQL 如何“防止幻读”?

方案一:锁定读(推荐)
select * from orders where price > 100 for update;
  • 会加Next-Key Lock(记录锁 + 间隙锁)
  • 锁住一个范围
  • 阻止其他事务插入新记录

从结果上看:幻读被避免

方案二:串行化隔离级别
  • 本质是用锁解决
  • 代价太高

四、MVCC:多版本并发控制的核心原理

MySQL 高并发性能的关键

MVCC 解决了什么问题?

  • 避免读写冲突
  • 提高并发性能
  • 实现非阻塞读

MVCC 的核心组件

(1)隐藏字段
  • trx_id:最后一次修改该行的事务 ID

  • roll_pointer:指向 undo log

(2)Undo Log
  • 保存数据的历史版本

  • 用于事务回滚 & MVCC

(3)Read View
  • 决定“当前事务能看到哪些版本”

一致性读流程(简化)

当前事务 → 生成 Read View → 判断记录 trx_id 是否可见 → 不可见 → 通过 undo log 找历史版本

MVCC + 锁的协作关系

场景机制
普通 selectMVCC
select for updateUpdate
update / delete
防止幻读Next-Key Lock

MVCC 解决“读一致性”,锁解决“写冲突”

总结

MySQL 默认使用可重复读隔离级别

MVCC 保证了:

  • 非阻塞读
  • 高并发性能

幻读并不是完全由 MVCC 解决

锁定读 + Next-Key Lock才是幻读的真正终结者

MySQL 的事务模型,本质是:

MVCC + 锁机制的精妙组合

http://www.jsqmd.com/news/150189/

相关文章:

  • 2025年东莞肥仔秋食品公司深度解析:地标美食品牌核心竞争力与市场战略权威指南 - 品牌企业推荐师(官方)
  • NVIDIA NGC目录中TensorRT资源获取完全指南
  • SpringMVC新版本踩坑[已解决] - 详解
  • Trae智能体SOLO中国版
  • 2025年高效喷淋塔厂家推荐:武汉熙诚环保科技领衔,PP废气净化塔与酸雾喷淋塔实力品牌深度解析 - 品牌企业推荐师(官方)
  • ABC438
  • 构建自动化CI/CD流程:TensorRT模型持续集成
  • Java计算机毕设之基于Spring Boot 社区助老志愿者服务平台的设计与实现基于springboot的老年志愿者服务智慧平台(完整前后端代码+说明文档+LW,调试定制等)
  • 计算机Java毕设实战-基于JAVA技术的电商精准营销推荐系统设计及实现基于Spring Boot的电商精准营销推荐系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java毕设选题推荐:基于JAVA技术的电商精准营销推荐系统设计及实现基于Javaweb的电商平台个性化推荐系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 使用TensorRT优化LayoutParser文档解析模型
  • 基于TensorRT的智能客服系统并发能力提升三倍
  • 【收藏必备】程序员转型大模型AI:90天学习路径与高薪就业指南
  • Java毕设项目:基于JAVA技术的电商精准营销推荐系统设计及实现(源码+文档,讲解、调试运行,定制等)
  • YOLO11 Neck改进:引入密集连接DenseNet思想,在FPN/PANet的融合路径上,引入密集连接,让每个层都能接收到前面所有层的特征,增强特征流通
  • 如何在大学期间高效专注学习 Java:拒绝恋爱、闲聊与短视频的自律成长指南
  • NVIDIA Driver版本与TensorRT兼容性注意事项
  • NVIDIA Orin芯片上部署TensorRT自动驾驶模型案例
  • 转行AI大模型算法工程师,如何在人工智能领域实现职业跃迁
  • 甲骨文文字检测数据集VOC+YOLO格式6079张1类别
  • Redis 为什么能扛住百万并发?一文吃透它的四大核心设计哲学
  • 【毕业设计】基于springboot的老年志愿者服务智慧平台(源码+文档+远程调试,全bao定制等)
  • 鲲鹏原生加速之力:BoostKit KVecTurbo 源码解析与实战
  • 行业数据 benchmark 对比:DeepSeek上传数据生成竞品差距分析报告
  • 构建统一推理框架:TensorRT作为核心执行单元
  • 分布式并发更新指南:乐观锁、悲观锁、Redis 锁与消息队列
  • awk项目练习以及阶段项目
  • 2025 MBA必备!8个降AI率工具测评榜单
  • 计算机Java毕设实战-基于Spring Boot 社区助老志愿者服务平台的设计与实现基于springboot的老年志愿者服务智慧平台【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 【课程设计/毕业设计】基于springboot的老年志愿者服务智慧平台活动发布、健康监测、紧急呼叫【附源码、数据库、万字文档】