MySQL篇1——MySQL深度揭秘:事务隔离级别与 MVCC 原理详解

在数据库系统中,为了确保数据的正确性与一致性,引入了事务机制。一个事务代表着数据库执行的最小逻辑单元。


一、事务的四大特性(ACID)与实现原理

特性 描述 MySQL 依赖机制
原子性 Atomicity 事务中的操作要么全部执行成功,要么全部回滚 Undo Log(回滚日志)
一致性(目的) Consistency 事务前后数据需保持一致 依赖原子性+隔离性+持久性共同保证
隔离性 Isolation 并发事务之间互不影响 锁机制、MVCC
持久性 Durability 提交后的数据永久保存,即使系统宕机也不丢失 Redo Log(重做日志)

✔一致性是目的,其余三个是手段。


二、并发事务可能出现的问题

问题 含义 举例说明
脏读 Dirty Read 读取了其他事务未提交的数据 余额被读到未提交的修改
不可重复读 Non-repeatable Read 同一事务内两次读取同一行却得到不同结果 第二次读取时数据已被他人修改并提交
幻读 Phantom Read 同条查询条件返回的记录数不一致 第一次无结果 → 第二次新增了符合条件的数据

脏读问题展示:读到了脏数据,事务1修改了以后没提交就被事务2读了,这时候事务1回滚了。

不可重复读问题展示(一个事务中两次读取):事务1查询得到1000,这时候事务1还没结束,但是事务2修改了balance,事务1又读了一次发现是800。

幻读问题展示:事务1去汇总整个表的用户余额得到3000,这时候还没结束结束,事务二给一个用户加了1000余额,事务1又查了一次发现变成了4000。

幻读问题展示(场景2):当事务1去查询某个表发现没这个记录,他就想插入记录,但是插入的时候发现这个记录又存在了(就好像出现了幻觉),原因就是中途事务2刚好插入了这条数据。


三、事务隔离级别与解决效果

首先明白一点:隔离级别就是对应就是解决并发事务出现的问题。

名词理解:

读未提交:一个事务还没提交时,它做的变更就能被别的事务看到。

读已提交:一个事务提交之后,它做的变更才会被其他事务看到。

可重复读:在一个事务中前后两次重复读取同一条数据,数据内容一致。

串行化:通过加锁的方式让整个过程串行起来。对于同一行记录,"写"会加"写锁","读"会加"读锁"。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

表格总览------SQL 标准定义四种隔离级别:

隔离级别 简称 脏读 不可重复读 幻读 实现方式 InnoDB 默认
读未提交 RU
读已提交 RC ✔️ MVCC
可重复读 RR ✔️ ✔️ ❓标准存在,MySQL无 MVCC + 间隙锁
串行化 Serializable ✔️ ✔️ ✔️ 加锁

MySQL InnoDB 在可重复读(RR)级别下,可通过 间隙锁(Gap Lock) 避免幻读。


四、什么是 MVCC(多版本并发控制)

MVCC 的核心目标是:

允许多事务并发读写,并尽量避免加锁阻塞,从而提高性能

其本质是在数据上维护多个版本,通过快照读来实现非阻塞读取。

简单来说就是:它是mysql在innodb存储引擎下实现rr和rc的一种手段,它通过维护行记录的多个不同的版本,通过链的形式连接起来,然后比如在select的时候通过MVCC机制去判断到底用哪一个版本。

具体实现主要分为三大部分:两个主要的隐藏字段,undo版本链,ReadView


MVCC 依赖的关键结构

名称 作用
行隐藏字段 trx_id 表示版本由哪个事务创建
行隐藏字段 roll_pointer 指向 undo log 中的上一个版本
Undo Log(版本链) 保存历史版本,实现回滚和多版本访问
ReadView(读视图) 决定事务能看到哪些版本

undo版本链示例(越下越旧)

cpp 复制代码
最新版本 (trx_id = 20)
      ↓ roll_pointer
上一个版本 (trx_id = 18)
      ↓ roll_pointer
更旧版本 ...

五、ReadView(快照)可见性规则

事务读取数据时,根据版本的 trx_id 判断可见性:

判断条件 能否访问 说明
trx_id == 当前事务ID 自己的版本可读
trx_id < min_trx_id 版本创建事务已提交
trx_id ≥ max_trx_id 版本在快照之后才开始创建
min_trx_id ≤ trx_id < max_trx_id 且在 m_ids 中 创建事务未提交
min_trx_id ≤ trx_id < max_trx_id 且不在 m_ids 中 创建事务已提交

不可见时则通过 roll_pointer 找到可读的历史版本。

最后:要么查不到(都不符合可见性条件),要么查到的就是该事务能看到的"最新合法版本"


六、RC 与 RR 的根本区别:ReadView 生成时机不同

隔离级别 生成策略 导致现象
读已提交(RC) 每次查询都会生成新 ReadView 数据可见版本会变化 → 会出现不可重复读
可重复读(RR) 仅第一次查询创建 ReadView 并复用 快照固定 → 保证可重复读

一句话理解:

RR 固定快照,RC 不固定快照 → RC 更实时,RR 更一致性能


七、总结

控制手段 主要作用 局限性
MVCC 避免读写阻塞,性能好 单独无法完全杜绝幻读
间隙锁 解决幻读问题 降低并发性能
串行化 强一致性 性能最差

总结一句话

InnoDB 通过 MVCC + 锁机制 实现高并发下的事务隔离,RR 默认隔离级别结合间隙锁避免幻读,保证数据一致性。

相关推荐
佛祖让我来巡山4 小时前
【面试题】数据库事务隔离与传播属性是什么?
事务·隔离级别·mvcc·不可重复读·幻读·脏读·传播属性
韩立学长4 小时前
【开题答辩实录分享】以《自助游网站的设计与实现》为例进行选题答辩实录分享
java·mysql·spring
SAP小崔说事儿4 小时前
在数据库中将字符串拆分成表单(SQL和HANA版本)
java·数据库·sql·sap·hana·字符串拆分·无锡sap
川贝枇杷膏cbppg5 小时前
asmcmd
数据库·oracle
JIngJaneIL6 小时前
基于java+ vue助农电商系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
q_19132846956 小时前
基于Springboot+MySQL+RuoYi的会议室预约管理系统
java·vue.js·spring boot·后端·mysql·若依·计算机毕业设计
IndulgeCui6 小时前
基于CentOS7 DM8单机部署配置记录-20251216
数据库
surtr16 小时前
关系代数与关系型数据库
数据库·sql·数据库系统
学海_无涯_苦作舟6 小时前
MySQL面试题
数据库·mysql·面试
老邓计算机毕设6 小时前
SSM校内二手书籍交易系统的设计与实现an1k0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·ssm 框架开发·ssm 校内二手书籍交易系统