ACID是InnoDB通过undo log、redo log、MVCC和锁机制协同实现的整体结果:原子性靠undo log回滚,持久性靠redo log+doublewrite,隔离性靠MVCC+行锁,一致性是前三者共同保障的最终效果。

直接学原理,别从定义开始背。ACID不是四个孤立概念,而是InnoDB引擎用几类日志和机制协同工作的结果。抓住“日志+锁+版本”三条主线,就能串起全部逻辑。
原子性:靠 undo log 做“后悔药”
事务执行中途出错或主动 rollback,MySQL 要能把已改的数据“撤回去”。这不是靠记操作步骤,而是靠 undo log——它在修改数据前,先存下旧值(比如 update 前的行内容)。回滚时,InnoDB 就按 undo log 里的旧值把数据还原。
- insert 回滚 → 执行 delete
- delete 回滚 → 执行 insert(还原被删的行)
- update 回滚 → 执行反向 update(把字段值改回原来)
- undo log 还带隐藏字段 roll_ptr,指向该行历史版本,支撑 MVCC
持久性:靠 redo log + doublewrite 保“不丢”
commit 后数据必须落盘,但直接写磁盘太慢。InnoDB 先写 redo log(重做日志),记录“某页某偏移处要改成什么”,再异步刷盘。崩溃恢复时,用 redo log 把没写进数据文件的修改重放一遍。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- redo log 是物理日志,格式紧凑、顺序写,速度快
- doublewrite 机制防止页写半截(partial page write),提升可靠性
- binlog 是逻辑日志,用于主从复制和归档,不参与 crash recovery
隔离性:MVCC + 行锁解决“并发干扰”
多个事务同时读写,不能互相踩脚。InnoDB 不靠简单加锁堵死所有并发,而是用 MVCC(多版本并发控制)让读不阻塞写、写不阻塞读(快照读),再配合行锁处理写冲突(当前读)。
立即学习“Java免费学习笔记(深入)”;
- 每个事务有唯一 trx_id,每行记录带 db_trx_id(最后修改它的事务 ID)和 roll_ptr
- SELECT 不加锁 → 走 MVCC,按自己的 snapshot 读可见版本
- UPDATE/DELETE/SELECT FOR UPDATE → 加行锁,同时查最新版本(当前读)
- RR 隔离级别下,快照基于事务启动时的活跃事务列表确定
一致性:是 ACID 的结果,不是独立实现
一致性不是某个模块单独保证的,而是原子性、隔离性、持久性共同作用达成的效果。比如转账总金额不变,靠的是:原子性确保扣+增不半途而废;隔离性防止并发时重复扣款或漏加;持久性确保提交后不会丢失。约束(主键、外键、check)也由引擎在事务提交前校验。
- 外键约束失败 → 事务自动 rollback
- 唯一索引冲突 → INSERT 失败,触发回滚逻辑
- 应用层业务规则(如余额不能为负)需靠 SQL 条件或触发器+事务包裹来兜底

















