一致性问题域与 CAP/BASE
用途:判断“这个场景到底需不需要分布式事务”时先读这一页
问题的来源
「问题的来源」小节链接单个数据库事务能解决同一资源内的一致性(ACID)。一旦业务操作跨越多个资源——多个库、消息中间件、外部系统——就不存在一个统一提交点,事务保证随之失效。此时可选的性质只有三类:强一致(阻塞换取一致)、最终一致(允许短暂不一致)、放弃(接受不一致并靠对账发现)。
CAP 与它的常见误读
「CAP 与它的常见误读」小节链接CAP 指分布式存储在网络分区(P)必然发生的前提下,只能在一致性(C)与可用性(A)之间取舍。
误读点:
- CAP 描述的是分区发生时的行为,不是常态。没分区时既可以提供强一致也可以高可用。
- 这里的 C 指线性一致,与 ACID 的 C(业务约束不被破坏)不是同一个概念。
- CAP 是存储层结论,不能直接推导“业务系统该怎么设计”。
实际工程更常用 PACELC 的补充视角:有分区时牺牲 C 或 A,没分区时也要在延迟(L)与一致性(C)之间取舍——这才是跨机房、跨库读写延迟问题的真实来源。
BASE 的含义
「BASE 的含义」小节链接Basically Available(基本可用)、Soft state(软状态,允许中间态)、Eventually consistent(最终一致)。落地形式就是:主流程本地事务提交,次要影响异步完成,配合重试、幂等与对账收敛。
“基本可用”的具体形态:功能降级、响应时间变长、部分用户被排队——不是“随便挂”。
决策树
「决策树」小节链接| 问题 | 若是 | 建议 |
|---|---|---|
| 是否跨多个独立数据源? | 否 | 单库事务即可,别引入分布式事务 |
| 不一致是否会造成资金/合规损失? | 是 | 强一致方案(同库、XA/TCC)或改为同一聚合 |
| 能否接受秒级到分钟级不一致? | 是 | 本地消息表/事务消息 + 幂等消费 + 对账 |
| 参与方是否包含不可控外部系统? | 是 | 最大努力通知 + 主动查询 + 对账 |
| 流程是否长、跨天、含人工环节? | 是 | Saga(补偿型),避免长时间持锁 |
最有价值的一步往往是消除事务需求本身:把强一致的部分收进同一个聚合与同一个库,剩下的用最终一致处理。跨库强一致方案的复杂度通常高于“重新划分边界”的成本。
兜底三件套
「兜底三件套」小节链接任何异步一致性方案都必须同时具备:
- 幂等:重复投递不产生重复效果(业务幂等键,而非消息 ID)。
- 重试与死信:失败可重放,且有人负责处理堆积。
- 对账:定期比对两侧状态,发现并修复偏差;对账是“最终一致”唯一的证据来源。
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 用 CAP 论证“我们选 AP 所以可以不一致” | 明确业务能容忍的不一致窗口与后果,再选方案 |
| 认为消息中间件保证恰好一次 | 端到端只能靠生产可靠 + 消费幂等逼近 |
| 只上“事务消息”就宣布一致 | 没有对账,就没有证据 |
| 把补偿逻辑当可选项 | Saga/TCC 的失败率高于正向流程,补偿必须与正向同等严谨 |
延伸阅读
「延伸阅读」小节链接- Eric Brewer 关于 CAP 的原始论述与 later clarifications
- Martin Kleppmann《数据密集型应用系统设计》第 8、9 章(一致性与共识)
- Chris Richardson《微服务架构设计模式》第 4、8、9 章(Saga、事件驱动与一致性)
- Pat Helland《Life beyond Distributed Transactions》