ACID
ACID 描述事务对外承诺的四个核心性质,以及数据库为了实现这些性质必须协调的提交、隔离与恢复机制。
#type / concept
#status / growing
#tech / dev / backend
#resource / database
[!info] related notes
ACID
一句话定义
ACID 是事务对外承诺的四个核心性质:Atomicity、Consistency、Isolation、Durability,用来描述“这次提交到底算不算正确成立”。
为什么 ACID 不是四个宣传词
很多初学者把 ACID 当成一组口号,但数据库实现里,它其实是在回答四个不同问题:
- 这组操作能不能只成功一半
- 提交前后有没有破坏约束和业务不变量
- 并发事务会不会互相看见不该看见的中间状态
- 提交成功后遇到崩溃还能不能恢复回来
这四个问题共同构成了“事务可信”的最小标准。
核心机制 / 工作原理
1. Atomicity 原子性
原子性回答的是:
事务里的多个动作,能不能只完成其中一部分。
原子性的要求是:
- 全部成功,再一起算成功
- 中间任何一步失败,都要能撤销已经做过的修改
它背后通常依赖:
- 回滚能力,例如 Undo Log
- 事务状态管理
- 提交点之前的错误处理和异常恢复
原子性强调的是“全成全败”,不是“执行速度快”或“只有一条 SQL”。
2. Consistency 一致性
一致性回答的是:
事务提交前后,数据库是否仍满足它承诺的规则。
这些规则既可能来自数据库,也可能来自业务:
- 主键、外键、唯一约束、检查约束
- 非空、引用完整性
- 账户余额不能为负
- 一笔订单不能既是已支付又是已取消
一致性最容易被误解的地方在于:
- 它不是单纯等于“数据长得像没坏”
- 它不只靠数据库内核自动完成
- 如果应用把本该放在同一个事务里的操作拆散,一致性仍然可能被破坏
换句话说,数据库能提供工具,但业务不变量最终仍要靠建模和事务边界一起守住。
3. Isolation 隔离性
隔离性回答的是:
当多个事务同时运行时,它们会不会互相看见不完整状态,或者彼此干扰到结果错误。
隔离性的目标不是让事务“彼此完全不存在”,而是让并发执行的结果尽量等价于某种合理的串行顺序。
数据库通常会结合下面几类机制来实现隔离:
隔离性不是开或不开的二元选项,而是一组强弱不同的保证。
4. Durability 持久性
持久性回答的是:
一旦事务提交成功,结果能不能在崩溃后仍被恢复出来。
这里的重点不是“数据页立刻刷盘”,而是:
- 提交所需的恢复信息已经安全保存
- 即使此刻断电,数据库重启后也能把已提交结果重做出来
这通常依赖:
所以持久性的承诺本质上是“可恢复”,不是“所有东西已经彻底写到底层文件”。
最小例子 / 最小场景
转账事务里:
- Atomicity 保证“扣钱和加钱”不能只成功一半
- Consistency 保证不会违反余额约束、账户约束和流水约束
- Isolation 保证别人不会在中途看到一边扣了、另一边还没加
- Durability 保证
COMMIT成功后即使数据库重启,结果也应存在
这个例子也说明 ACID 的四项并不是互相替代,而是在看同一事务的不同侧面。
从原理上看,四个字母分别依赖什么
| 性质 | 主要回答的问题 | 常见支撑机制 |
|---|---|---|
| Atomicity | 能不能全成全败 | 事务状态、回滚链路、[[undo-log |
| Consistency | 是否守住约束和不变量 | 约束系统、正确事务边界、应用业务规则 |
| Isolation | 并发下会不会互相踩踏 | [[transaction-isolation-levels |
| Durability | 提交后宕机还能不能恢复 | [[redo-log |
边界与易混淆点
- ACID 不等于“数据库绝不会出错”,它只是数据库对事务语义的目标承诺。
- 一致性和隔离性不是同一个东西。一致性关注最终是否守住规则,隔离性关注并发过程里能否互不干扰。
- 持久性不等于“提交时所有脏页都刷盘”。更准确地说,是恢复所需信息已经安全保存。
- 原子性也不等于“单条语句天然就绝对安全”。单语句只是事务边界可能更小,不代表没有回滚、锁或恢复问题。
- ACID 主要描述单数据库事务的语义。跨数据库、跨消息队列、跨外部服务时,需要额外的一致性设计。