🧠 一、事务的定义与四大特性(ACID)
| 特性 | 含义 |
|---|---|
| A(原子性) | 要么都成功,要么都失败 |
| C(一致性) | 数据前后满足完整性约束 |
| I(隔离性) | 多事务并发,互不干扰(具体级别控制) |
| D(持久性) | 一旦提交,对数据的更改是永久的 |
⚙️ 二、MySQL 中事务的实现机制
✅ 1. 基于 InnoDB 存储引擎 的事务实现
MySQL 支持事务的存储引擎主要是 InnoDB,通过以下几个组件协同工作:
| 组件 | 作用 |
|---|---|
| Redo Log(重做日志) | 保证持久性,崩溃后可恢复已提交事务 |
| Undo Log(回滚日志) | 支持原子性与隔离性,回滚操作与 MVCC |
| Binlog(归档日志) | 主从复制 & 增量备份使用 |
| MVCC(多版本并发控制) | 提高并发能力,实现 RC 或 RR 隔离级别 |
🔄 2. 事务的执行流程(简化版)
-
开启事务:BEGIN 或自动事务(autocommit = 0)
-
执行 DML 操作(如
UPDATE):-
写入 Undo Log(记录修改前数据)
-
写入 Redo Log(Prepare 状态)
-
-
提交事务:
-
将 Redo Log 标记为 Commit 状态
-
Binlog 持久化(顺序依赖)
-
-
崩溃恢复时:使用 Redo + Undo 确保数据一致性
🔐 三、事务隔离级别与实现方式(MVCC)
| 隔离级别 | 幻读 | 可重复读 | 脏读 | 实现方式 |
|---|---|---|---|---|
| READ UNCOMMITTED | ✅ | ✅ | ✅ | 不加锁 |
| READ COMMITTED | ✅ | ✅ | ❌ | MVCC,读取最新提交版本 |
| REPEATABLE READ(默认) | ❌ | ❌ | ❌ | MVCC,读取事务开始时快照 |
| SERIALIZABLE | ❌ | ❌ | ❌ | 全表加锁,性能差 |
InnoDB 默认使用 REPEATABLE READ + MVCC,可避免幻读,无需显式加锁。
🔍 四、面试答题模板:MySQL 是如何实现事务的?
MySQL 的事务由 InnoDB 存储引擎实现,核心依赖 Undo Log、Redo Log 与 Binlog 的组合来保证事务的 ACID 特性:
原子性:通过 Undo Log 回滚未完成事务;
持久性:通过 Redo Log + 两阶段提交保障已提交数据不丢失;
一致性:事务前后数据满足约束;
隔离性:通过 MVCC + 隔离级别保证并发事务间相互隔离。
实际项目中我会设置合理的事务粒度、使用 Spring 的事务控制,并配合悲观/乐观锁策略保障业务一致性。
🧪 五、场景举例
📌 1. 支付场景:事务 + 幂等控制
@Transactional
public void pay(Order order) {
if (alreadyPaid(order.getId())) return;
deductBalance(order.getUserId());
updateOrderStatus(order.getId());
}
📌 2. 主从架构下注意点
事务在主库生效,但主从延迟可能导致读写不一致,需搭配 读写分离策略、幂等处理。
📎 六、拓展知识:事务的两阶段提交(2PC)
MySQL 内部实现事务时,涉及 两阶段提交(先 Redo Prepare,再 Commit):
| 阶段 | 操作 |
|---|---|
| 1️⃣ Prepare 阶段 | 写入 Redo Log,标记为 prepare,保证崩溃后仍可回滚 |
| 2️⃣ Commit 阶段 | 写入 Binlog,然后标记 Redo Log 为 commit |
保证了崩溃恢复时,不会产生“已提交数据丢失”的问题。


被折叠的 条评论
为什么被折叠?



