MySQL 事务与隔离级别完全指南

概览

本文系统梳理 MySQL 事务控制与并发隔离机制,从核心概念到实战操作,帮助你彻底掌握事务管理。


一、事务(Transaction)基础

1.1 什么是事务

事务是一组逻辑相关的 SQL 操作,要么全部成功 ,要么全部失败,保证数据的一致性。

1.2 事务的四大特性(ACID)

特性 英文 含义 记忆口诀
原子性 Atomicity 事务中所有操作不可分割,要么全做要么全不做 A------All or Nothing
一致性 Consistency 事务前后数据必须保持一致状态(如转账前后总金额不变) C------前后一致
隔离性 Isolation 并发事务之间互不干扰 I------互不干扰
持久性 Durability 事务一旦提交,修改永久保存,即使系统崩溃也不丢失 D------提交即永久

💡 记忆技巧:ACID = 原子 → 一致 → 隔离 → 持久,四个字母顺读即可。

1.3 事务的生命周期

复制代码
START TRANSACTION ──→ 执行SQL操作 ──→ COMMIT (提交)
                                  └──→ ROLLBACK (回滚)
  • 开启 :START TRANSACTION 或 BEGIN
  • 提交 :COMMIT------永久保存修改,事务结束
  • 回滚 :ROLLBACK------撤销所有未提交的修改,事务结束

1.4 核心操作实战示例

场景:银行转账
sql 复制代码
-- 开启事务
START TRANSACTION;

-- 第一步:付款方转出
UPDATE account SET balance = balance - 200 WHERE name = '张三';

-- 第二步:收款方转入
UPDATE account SET balance = balance + 200 WHERE name = '李四';

-- 提交事务(两步同时成功才提交)
COMMIT;

如果在第二步之前执行 ROLLBACK,所有修改都会被撤销,数据恢复到事务开始前的状态。

1.5 SAVEPOINT(保存点)

保存点允许在事务中设置"标记点",实现部分回滚:

sql 复制代码
START TRANSACTION;

UPDATE account SET balance = balance - 50 WHERE name = '张三';
SAVEPOINT sp1;  -- 设置保存点 sp1

UPDATE account SET balance = balance + 50 WHERE name = '李四';
SAVEPOINT sp2;  -- 再设一个保存点 sp2

UPDATE account SET balance = balance - 100 WHERE name = '张三';

-- 回滚到指定保存点(sp1 之后的操作被撤销)
ROLLBACK TO sp1;

COMMIT;  -- 提交:张三减少50,李四不变

📌 规律总结 :SAVEPOINT 像"存档点",ROLLBACK TO 可以回到任意存档点继续操作,但 ROLLBACK(不带 TO)会回滚整个事务。

1.6 自动提交 vs 手动提交

模式 说明
自动提交(默认) 每条 SQL 语句执行后立即提交
手动提交 关闭自动提交后,需要显式 COMMIT 或 ROLLBACK
sql 复制代码
-- 查看当前自动提交状态
SELECT @@autocommit;  -- 1 = 开启,0 = 关闭

-- 关闭自动提交
SET AUTOCOMMIT = 0;

UPDATE account SET balance = balance + 100 WHERE name = '张三';
COMMIT;  -- 必须显式提交

-- 恢复自动提交
SET AUTOCOMMIT = 1;

⚠️ 注意 :START TRANSACTION 会隐式关闭自动提交,事务结束后恢复原状态。


二、事务并发问题

多个事务同时操作同一数据时,可能引发三类并发问题:

2.1 三大并发问题

问题 英文 描述 示例
脏读 Dirty Read 读到其他事务尚未提交的数据 张三改余额 1000→800(未提交),李四查到 800;张三回滚后,李四的 800 就成了脏数据
不可重复读 Non-Repeatable Read 同一事务中,两次读取同一行结果不同(UPDATE 引起) 李四查余额得 1000,张三改成 800 并提交,李四再查得 800
幻读 Phantom Read 同一事务中,两次查询结果集的行数不同(INSERT/DELETE 引起) 李四用 WHERE age>20 查有 5 条,别人插入一条符合条件的记录,再查变成 6 条
  • 不可重复读 → 同一行数据的值变了(UPDATE)
  • 幻读 → 结果集的行数变了(INSERT/DELETE)

三、四种隔离级别

3.1 级别详解

隔离级别决定了"多个事务同时操作时,彼此能看到对方多少操作"的规则。

第 1 级:读未提交(Read Uncommitted)
  • 🔴 比喻:你写日记还没合上,别人就凑过来看了。
  • 解决:无
  • 存在问题:脏读、不可重复读、幻读
  • 性能:最高
  • 使用场景:几乎不用
第 2 级:读已提交(Read Committed)
  • 🟡 比喻:你写日记,必须等你合上本子(提交)后,别人才能看。
  • 解决:脏读 ✅
  • 存在问题:不可重复读、幻读
  • 性能:较快
  • 使用场景:Oracle 默认级别
第 3 级:可重复读(Repeatable Read)
  • 🟢 比喻:看电影时领了 3D 眼镜,整场戴着看到的画面始终一样。
  • 解决:脏读 ✅、不可重复读 ✅
  • 存在问题:幻读
  • 性能:中等
  • 使用场景 :MySQL 默认级别,实际开发最常用 ★

💡 原理:MySQL InnoDB 通过**事务快照(MVCC)**实现可重复读------同一事务中多次读取看到的是同一份历史快照数据,不受其他事务提交的影响。

第 4 级:串行化(Serializable)
  • 🔵 比喻:整个银行网点同时只办一笔业务,其他人排队等待。
  • 解决:脏读 ✅、不可重复读 ✅、幻读 ✅
  • 性能:最差
  • 使用场景:极少使用,仅在对数据一致性要求极端严格时考虑

3.2 对比总结表

隔离级别 脏读 不可重复读 幻读 性能 备注
Read Uncommitted ❌ ❌ ❌ 最快 几乎不用
Read Committed ✅ ❌ ❌ 较快 Oracle 默认
Repeatable Read ✅ ✅ ❌ 中等 MySQL 默认 ★
Serializable ✅ ✅ ✅ 最慢 极少使用

📌 记忆口诀 :隔离级别从低到高,解决的问题越来越多,性能越来越差。脏读→不可重复读→幻读,逐个解决。

四、隔离级别操作命令

4.1 查询当前隔离级别

sql 复制代码
-- 查询当前会话的隔离级别
SELECT @@tx_isolation;       -- MySQL 5.x
SELECT @@transaction_isolation;  -- MySQL 8.0+

-- 查询全局隔离级别
SELECT @@global.tx_isolation;
SELECT @@global.transaction_isolation;

⚠️ 版本注意 :MySQL 5.x 使用 @@tx_isolation,MySQL 8.0+ 改为 @@transaction_isolation。

4.2 设置隔离级别

sql 复制代码
-- 语法:SET [作用域] TRANSACTION ISOLATION LEVEL [级别];
-- 作用域:SESSION(当前会话)| GLOBAL(全局)| 省略(下一个事务)

-- 设置为读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- 设置为读已提交
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 设置为可重复读(MySQL 默认)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 设置为串行化
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 永久修改(所有新连接生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

4.3 作用域说明

作用域 影响范围 持久性
省略(默认) 下一个即将开启的事务 一次性
SESSION 当前会话的所有后续事务 当前会话有效,断开后恢复
GLOBAL 所有新连接的默认隔离级别 永久(重启后失效,需改配置文件)

五、事务控制语句速查表

语句 作用
START TRANSACTION / BEGIN 开启一个新事务
COMMIT 提交事务,永久保存修改,结束事务
ROLLBACK 回滚事务,撤销所有未提交的修改,结束事务
SAVEPOINT name 在事务中设置一个保存点
ROLLBACK TO name 回滚到指定保存点,事务不结束
SET AUTOCOMMIT = 0/1 关闭/恢复自动提交模式

六、核心注意事项

6.1 事务边界

  • COMMIT 或 ROLLBACK 执行后,当前事务自动结束
  • 执行 DDL 语句(如 CREATE TABLE、ALTER TABLE)会隐式提交当前事务
  • 客户端连接断开时,未提交的事务会自动回滚

6.2 选择隔离级别的建议

场景 推荐级别 理由
大多数业务场景 Repeatable Read MySQL 默认,平衡了一致性与性能
高并发 OLTP 系统 Read Committed 减少幻读开销,Oracle 标准配置
对一致性要求极高 Serializable 保证数据绝对一致,但性能代价大

6.3 常见误区

误区 正解
ROLLBACK 可以回滚已 COMMIT 的数据 ❌ COMMIT 后数据已永久保存,无法通过 ROLLBACK 恢复
SAVEPOINT 可以跨事务使用 ❌ SAVEPOINT 仅在当前事务内有效,事务结束后自动清除
隔离级别越高越好 ❌ 级别越高性能越差,应根据业务需求选择
读已提交 = 没隔离 ❌ 它已解决了最严重的脏读问题,适合多数场景

七、知识体系图

复制代码
MySQL 事务管理
├── 核心特性 ACID
│   ├── Atomicity(原子性)
│   ├── Consistency(一致性)
│   ├── Isolation(隔离性)
│   └── Durability(持久性)
│
├── 控制语句
│   ├── START TRANSACTION / BEGIN
│   ├── COMMIT(提交)
│   ├── ROLLBACK(回滚)
│   ├── SAVEPOINT + ROLLBACK TO(部分回滚)
│   └── SET AUTOCOMMIT(自动提交开关)
│
├── 并发问题
│   ├── 脏读(Dirty Read)
│   ├── 不可重复读(Non-Repeatable Read)
│   └── 幻读(Phantom Read)
│
└── 隔离级别(低→高)
    ├── Read Uncommitted → 解决:无
    ├── Read Committed → 解决:脏读
    ├── Repeatable Read → 解决:脏读、不可重复读 ★MySQL默认
    └── Serializable → 解决:全部问题

八、记忆口诀汇总

知识点 口诀
ACID 特性 原子、一致、隔离、持久(A-C-I-D)
并发问题 脏读→不可重复读→幻读,一个比一个难搞
隔离级别选择 默认用可重复读,一致性极高才串行化
回滚规则 COMMIT 后不可回滚,SAVEPOINT 只在本事务有效
版本差异 MySQL 5.x 用 @@tx_isolation,8.0+ 用 @@transaction_isolation
相关推荐
lusklusklusk1 小时前
Sqlserver_Oracle_Mysql_Postgresql表_索引碎片或膨胀的知识点汇总
mysql·oracle·sqlserver
JosieBook2 小时前
【WinForm 代码反脆弱系列】04 数据库操作 —— 连接字符串、连接对象与连接池
数据库·oracle
小蒜学长2 小时前
基于SpringBoot+Vue的小学数学智能出题系统(代码+数据库+LW)
java·数据库·spring boot·后端·智能出题系统
71-32 小时前
MySQL密码重置
数据库·笔记·学习·mysql
锅里游的鱼吖3 小时前
echarts自定义折线图
前端·javascript·数据库
酷虎软件3 小时前
视频加标题字幕 API 接口文档
java·数据库·mysql
夜雪一千3 小时前
MySQL 触发器有哪些应用场景?从入门场景到避坑实战
数据库·mysql
lusklusklusk3 小时前
Oracle数据库基础之6_外部表临时表分区表_物化视图_约束的介绍
数据库·oracle
智商偏低3 小时前
【无标题】
服务器·数据库·oracle