主题
MySQL 事务
更新: 10/22/2025字数: 0 字 时长: 0 分钟
一、什么是事务(Transaction)
在 MySQL 中,事务(Transaction)是指一组操作,要么全部成功执行,要么全部失败回滚。事务可以保证数据库在出现异常(断电、错误、崩溃)时仍然保持数据一致性(Consistency)。
简单一句话:
事务 = 一组不可分割的数据库操作。
二、事务的四大特性(ACID 原则)
事务的核心特性通常被称为 ACID:
| 特性 | 名称 | 含义 |
|---|---|---|
| A | Atomicity(原子性) | 事务中的所有操作要么全部执行成功,要么全部失败并回滚 |
| C | Consistency(一致性) | 事务执行前后,数据必须保持一致(比如转账前后余额总和不变) |
| I | Isolation(隔离性) | 并发执行的多个事务互不影响 |
| D | Durability(持久性) | 一旦事务提交,其结果会永久保存到数据库中,即使系统崩溃也不会丢失 |
三、事务的基本操作
MySQL 默认使用 InnoDB 存储引擎,它是支持事务的。
常见的事务语句如下:
sql
-- 开启事务
START TRANSACTION;
-- 或者简写
BEGIN;
-- 执行多条语句
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 提交事务(确认执行)
COMMIT;
-- 如果出现错误则回滚
ROLLBACK;🌰 示例:模拟转账操作
假设 Alice 向 Bob 转账 100 元,我们需要保证两条 SQL 要么都执行,要么都不执行:
sql
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE name = 'Alice';
UPDATE accounts SET balance = balance + 100 WHERE name = 'Bob';
COMMIT;如果在执行第二条语句时出错:
sql
ROLLBACK;这样数据库就会恢复到事务开始之前的状态,保证数据一致性。
四、事务的自动提交机制
MySQL 默认是开启 自动提交模式 的(autocommit = 1)。也就是说,每执行一条语句就会自动提交。
可以通过以下命令查看或修改:
sql
-- 查看自动提交状态
SELECT @@autocommit;
-- 关闭自动提交
SET autocommit = 0;
-- 手动提交事务
COMMIT;五、事务隔离级别(Isolation Level)
当多个事务同时执行时,可能会出现一些并发问题,例如:
| 问题类型 | 说明 |
|---|---|
| 脏读(Dirty Read) | 事务读取了另一个事务尚未提交的数据 |
| 不可重复读(Non-repeatable Read) | 事务多次读取同一条记录,结果不一致 |
| 幻读(Phantom Read) | 事务多次查询发现数据条数发生了变化 |
MySQL 提供了 4 种隔离级别来解决这些问题:
| 隔离级别 | 描述 | 能防止的问题 |
|---|---|---|
| READ UNCOMMITTED | 可以读取未提交的数据 | 无法防止任何问题 |
| READ COMMITTED | 只能读取已提交的数据 | 防止脏读 |
| REPEATABLE READ (默认) | 多次读取结果一致 | 防止脏读、不可重复读 |
| SERIALIZABLE | 串行执行事务,性能最低 | 防止所有问题 |
设置隔离级别:
sql
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;六、事务日志(Redo Log & Undo Log)
InnoDB 为了保证 ACID 特性,底层依赖两种日志:
| 日志类型 | 作用 |
|---|---|
| Redo Log | 保证“持久性”,记录已提交事务的修改,用于崩溃恢复 |
| Undo Log | 保证“原子性”和“回滚”,记录事务未提交前的旧值 |
当事务提交后:
- Redo Log 会将修改刷入磁盘;
- Undo Log 会被清理;
- 系统崩溃时可用 Redo Log 恢复。
七、事务在应用中的最佳实践
✅ 1. 只在必要的地方使用事务 事务会加锁、影响性能,不要滥用。
✅ 2. 控制事务范围 避免在事务中执行长时间操作(如网络请求),防止锁等待或死锁。
✅ 3. 使用合适的隔离级别 业务允许的情况下,优先使用 READ COMMITTED 或默认的 REPEATABLE READ,性能更优。
✅ 4. 保持一致的事务管理方式 应用层(如 Node.js、Java、Python)也应与数据库层事务逻辑保持一致。