深入理解 MySQL 事务:从基础到实战,一篇吃透

在开发和运维 MySQL 数据库的过程中,事务(Transaction) 是绕不开的核心知识点,它是保证数据库数据安全、一致、可靠的基石。无论是电商下单、银行转账、支付结算,还是日常的业务数据操作,都离不开事务的支撑。

这篇文章会从事务的定义、四大特性(ACID)、隔离级别、并发问题、事务语法、实战案例、底层原理等维度,把 MySQL 事务讲得明明白白,新手也能轻松看懂、直接用。

一、什么是 MySQL 事务?

简单来说:事务是一组不可分割的数据库操作集合,要么全部执行成功,要么全部执行失败,不会出现中间状态。

举个最经典的例子:银行转账A 账户给 B 账户转 100 元,数据库需要执行两步操作:

  1. A 账户扣 100 元
  2. B 账户加 100 元

这两步必须同时成功 或者同时失败

  • 如果 A 扣钱了、B 没加钱 → 数据错乱,用户损失
  • 如果 A 没扣钱、B 加钱了 → 银行损失

事务就是用来杜绝这种中间状态,保证数据绝对可靠。


二、事务的四大特性:ACID

事务的核心就是 ACID 四大特性,这是面试必问、开发必懂的知识点。

1. 原子性(Atomicity)

定义 :事务是最小的执行单位,不可分割

  • 事务中的所有 SQL,要么全部执行成功,要么全部回滚(撤销)。
  • 只要有一步失败,整个事务都作废,数据回到执行前的状态。

2. 一致性(Consistency)

定义 :事务执行前后,数据库的完整性约束不被破坏

  • 转账前后,A 和 B 的总金额不变。
  • 数据始终符合业务规则,不会出现非法、错乱的数据。

3. 隔离性(Isolation)

定义 :多个事务并发执行时,互相不干扰,一个事务的中间状态对其他事务不可见。

  • 隔离性通过事务隔离级别实现,后面会详细讲。

4. 持久性(Durability)

定义 :一旦事务提交成功,对数据的修改是永久的

  • 即使数据库宕机、重启,数据也不会丢失。
  • 依靠 MySQL 的 redo log 实现持久化。

三、事务的并发问题(不隔离会怎样?)

如果多个事务同时操作同一份数据,不做隔离,会出现 4 种经典问题:

1. 脏读(Dirty Read)

一个事务读取到了另一个未提交事务修改的数据。

  • 例子:事务 1 修改数据但未提交,事务 2 读到了这个临时数据,结果事务 1 回滚了 → 事务 2 读到的是 "脏数据"。

2. 不可重复读(Non-Repeatable Read)

一个事务内,多次读取同一行数据,结果不一致

  • 原因:其他事务在这期间修改并提交了这行数据。

3. 幻读(Phantom Read)

一个事务内,多次查询的结果集行数不一致

  • 原因:其他事务在这期间插入 / 删除了符合条件的数据。

4. 丢失更新(Lost Update)

两个事务同时修改同一数据,后提交的事务覆盖了先提交的修改


四、事务的四大隔离级别

MySQL 提供了 4 种隔离级别,用来解决上面的并发问题,级别从低到高:

隔离级别 脏读 不可重复读 幻读 性能
读未提交(READ UNCOMMITTED) ✅ 允许 ✅ 允许 ✅ 允许 最高
读已提交(READ COMMITTED) ❌ 禁止 ✅ 允许 ✅ 允许
可重复读(REPEATABLE READ) ❌ 禁止 ❌ 禁止 ⚠️ 部分解决
串行化(SERIALIZABLE) ❌ 禁止 ❌ 禁止 ❌ 禁止 最低

重点说明:

  1. MySQL 默认隔离级别可重复读(REPEATABLE READ)
  2. InnoDB 存储引擎在 可重复读级别 下,通过 MVCC + 间隙锁 基本解决了幻读问题。
  3. 隔离级别越高,数据越安全,但并发性能越差
  4. 生产环境推荐使用:读已提交 或 可重复读

五、MySQL 事务基本语法

1. 开启事务

sql 复制代码
START TRANSACTION;
-- 或者简写
BEGIN;

2. 提交事务(永久生效)

sql 复制代码
COMMIT;

3. 回滚事务(撤销所有操作)

sql 复制代码
ROLLBACK;

4. 设置事务隔离级别

sql 复制代码
-- 会话级别(当前连接生效)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 全局级别(所有新连接生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

5. 查看当前隔离级别

sql 复制代码
SELECT @@transaction_isolation;

六、实战案例:银行转账(事务完整演示)

1. 创建测试表

sql 复制代码
CREATE TABLE account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    balance DECIMAL(10,2)
);

INSERT INTO account(name, balance) VALUES 
('张三', 1000.00),
('李四', 1000.00);

2. 正常转账(提交事务)

sql 复制代码
-- 开启事务
BEGIN;

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

-- 2. 李四加 100
UPDATE account SET balance = balance + 100 WHERE name = '李四';

-- 确认无误,提交
COMMIT;

执行后:张三 900,李四 1100 ✅

3. 异常转账(回滚事务)

sql 复制代码
BEGIN;

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

-- 模拟异常(比如程序报错、网络中断)
-- 直接回滚,所有操作作废
ROLLBACK;

执行后:数据回到原来的状态,没有任何修改


七、事务的底层原理(进阶)

想真正吃透事务,必须了解它的底层实现机制

1. redo log(重做日志)

  • 保证持久性
  • 记录 "修改了什么数据",数据库宕机重启后,通过 redo log 恢复数据

2. undo log(回滚日志)

  • 保证原子性
  • 记录修改前的数据,事务回滚时,用 undo log 恢复数据

3. MVCC(多版本并发控制)

  • 保证隔离性
  • 实现无锁读写,提升并发性能
  • 是 MySQL 高效处理并发事务的核心

八、事务使用注意事项(生产必看)

  1. 事务要短小精悍不要在事务里执行耗时操作(远程调用、sleep、大量计算),否则会导致锁等待、性能暴跌。

  2. 避免长事务长事务会占用大量 undo log,导致数据库性能下降。

  3. 所有更新操作必须加事务尤其是涉及多表、多行的业务逻辑。

  4. 不要自动提交 生产环境建议关闭自动提交:SET autocommit = 0;

  5. 异常必须回滚 程序捕获异常时,一定要执行 ROLLBACK


九、总结

  1. 事务:一组操作,要么全成,要么全败。
  2. ACID:原子性、一致性、隔离性、持久性,事务的灵魂。
  3. 并发问题:脏读、不可重复读、幻读、丢失更新。
  4. 隔离级别 :MySQL 默认 可重复读,兼顾安全与性能。
  5. 核心命令BEGIN → 执行 SQL → COMMIT/ROLLBACK
  6. 底层:redo log、undo log、MVCC 共同支撑事务。

掌握 MySQL 事务,你就能写出安全、稳定、高并发的数据库程序,这是后端开发的核心基本功。

相关推荐
我科绝伦(Huanhuan Zhou)2 小时前
MySQL数据库备份管理系统新增备份任务巡检功能
运维·数据库·mysql
吠品2 小时前
Docker Desktop部署Weaviate向量数据库:从配置到生产环境全流程
数据库·oracle·eureka
tuokuac2 小时前
什么情况下type为index
mysql
倔强的石头1062 小时前
【Linux指南】基础IO系列(三):Linux 系统 IO 接口 —— 深入内核的文件操作
linux·数据库
拾起零碎2 小时前
U8/领料申请单SQL server触发器,如果自定义项13有值,把数量修改成件数乘以自定义项13,如果恰好件数等于现存量,则数量同步出空
数据库
磊 子2 小时前
Redis详解
linux·数据库·redis·缓存
夕除2 小时前
Mysql--14
数据库·mysql
014-code2 小时前
Java Optional 那些被忽略的用法
java·数据库·javase
qq_283720052 小时前
MySQL实战(十五): 常用内置函数实战--日期、字符串、数学函数从入门到精通
mysql·内置函数·日期函数·字符函数·日期计算