4、分布式事务基础:ACID 理论、CAP 定理、BASE 理论

聊 Exactly Once 语义,绕不开分布式事务。很多同学一听到「分布式事务」就头大,觉得这东西又慢又复杂。说实话,我早年也有这感觉。直到在线上环境被数据不一致坑过几次,才老老实实把基础补上。

这一章,咱们把三个最核心的理论掰开揉碎。ACID、CAP、BASE。它们不是教科书上的死概念,而是你设计系统时的「决策框架」。

4.1 ACID:单机数据库的「铁律」

ACID 是单机数据库的基石。你想想看,一个银行转账场景,A 扣 100,B 加 100。要么都成功,要么都失败。这就是事务。

特性 含义 我踩过的坑
原子性 (Atomicity) 事务要么全做,要么全不做 曾经在批量扣款时,中间一条失败,前面的已经提交了……
一致性 (Consistency) 事务前后,数据满足所有约束 这个更多是业务逻辑的事,数据库只管约束
隔离性 (Isolation) 并发事务互不干扰 默认的 Read Committed 级别,在账务系统里根本不够用
持久性 (Durability) 提交后,数据不会丢 MySQL 双 1 配置,刷盘是必须的
注意: ACID 是单机模型。一旦拆成多个数据库节点,ACID 的「一致性」和「隔离性」就很难保证了。这也是为什么我们需要 CAP 和 BASE。

我个人习惯把 ACID 理解成「单机事务的黄金标准」。在单体架构里,它非常好用。但到了分布式环境,你没法让所有节点都保持强一致,否则性能会崩。

4.2 CAP 定理:分布式系统的「不可能三角」

CAP 定理是分布式系统的「紧箍咒」。它说:一个分布式系统,最多只能同时满足 C、A、P 中的两个。

  • C (Consistency) 一致性:所有节点在同一时刻看到的数据是一样的。
  • A (Availability) 可用性:每个请求都能收到一个响应(不保证数据是最新的)。
  • P (Partition Tolerance) 分区容错性:系统内部分节点之间通信断了,系统还能继续工作。

为什么是「不可能三角」?我举个例子。假设两个节点 A 和 B,中间网络断了(分区发生)。这时候你写数据到 A,B 是不知道的。

  • 如果你选 CP:那 B 必须拒绝所有读请求,直到网络恢复。保证了数据一致,但牺牲了可用性。
  • 如果你选 AP:那 B 可以继续返回旧数据。保证了可用性,但数据可能不一致。

说白了,P 是必选的。因为网络分区一定会发生。你只能在 C 和 A 之间做取舍。

核心观点: 在分布式系统中,P 是必选项。你真正需要决策的是:当网络分区时,你选择「强一致」还是「高可用」?

我记得在做一个订单系统时,我们选了 AP。用户下单后,立即返回成功,但后台异步对账。结果有一次网络抖动,订单状态在数据库里乱掉了。嗯,那之后我们加了一层补偿机制。

4.3 BASE 理论:向现实妥协的「柔性事务」

BASE 理论是 eBay 的架构师 Dan Pritchett 提出的。它是对 CAP 中「AP」路线的一种实践总结。

缩写 全称 解释
BA Basically Available 基本可用。系统允许部分功能降级,比如双十一时,查询订单可以延迟几秒
S Soft State 软状态。数据允许中间状态,比如「支付中」「待确认」
E Eventually Consistent 最终一致。经过一段时间后,所有数据会达成一致

你想想看,BASE 其实就是放弃了 ACID 的强一致性,换来了更高的可用性和扩展性。它不要求数据时刻一致,只要求「最终一致」。

我的经验: 在设计最终一致的系统时,一定要考虑「冲突检测」和「补偿机制」。我曾经在消息队列里丢过一条消息,导致两个账户对不上账。后来加了幂等性和对账脚本,才算稳住。

4.4 三者的关系与选择

ACID、CAP、BASE 不是互斥的,而是不同场景下的不同选择。

  • 单机场景:用 ACID,简单可靠。
  • 分布式场景,要求强一致:选 CP,比如 Zookeeper、Etcd。
  • 分布式场景,要求高可用:选 AP + BASE,比如大部分互联网业务。

我建议你在设计系统时,先问自己三个问题:

  1. 这个数据允许不一致多久?
  2. 不一致了,能自动修复吗?
  3. 用户能接受偶尔的延迟或降级吗?

回答完这三个问题,你自然就知道该选哪条路了。

一句话总结: ACID 是理想,CAP 是现实,BASE 是妥协。没有银弹,只有 trade-off。

4.5 知识体系图

下面这张图,帮你理清这三个理论的关系和适用场景。

分布式事务基础理论体系 ACID 单机事务铁律 原子性 一致性 隔离性 持久性 CAP 定理 分布式不可能三角 一致性 (C) 可用性 (A) 分区容错 (P) P 是必选项 BASE 理论 柔性事务实践 基本可用 (BA) 软状态 (S) 最终一致 (E) 选择策略 单机 → ACID | 分布式强一致 → CP (如 ZK) | 分布式高可用 → AP + BASE 单机场景 ACID 简单可靠 强一致场景 CP 路线 高可用场景 AP + BASE

这张图从左到右,展示了从单机到分布式的演进路径。ACID 是起点,CAP 是约束,BASE 是解法。你不需要死记硬背,理解每个理论的「为什么」和「什么时候用」,比背概念重要得多。

一个小建议: 刚开始接触分布式事务的同学,别一上来就想着用两阶段提交(2PC)或者 TCC。先搞清楚你的业务到底需要多强的一致性。很多时候,一个消息队列加一个补偿脚本就能解决问题。