2. 分布式事务基础
在金融系统中,事务不是“提交成功”四个字那么简单。一次转账、一笔支付、一次账务记账,背后往往跨越多个数据库、多个服务、甚至多个机房。理解分布式事务,必须先回到事务理论的根基:ACID、CAP、BASE,以及本地事务与分布式事务的本质差异。
一、ACID:单库事务的四个支柱
ACID 是本地事务的经典定义,也是金融系统最熟悉的一致性语言:
- 原子性(Atomicity):事务内的操作要么全部成功,要么全部回滚。转账中“扣款”和“入账”不能只发生一半。
- 一致性(Consistency):事务前后数据满足业务约束,例如借贷平衡、账户余额不为负。
- 隔离性(Isolation):并发事务之间互不干扰,常见隔离级别包括读未提交、读已提交、可重复读、串行化。
- 持久性(Durability):事务提交后,即使断电或宕机,结果也不能丢失。
在单库场景中,数据库通过 undo/redo 日志、锁机制和 MVCC 来保证 ACID。例如 MySQL 的 InnoDB 在可重复读级别下,通过 next-key lock 避免幻读,通过 redo log 保证持久性。但一旦事务跨越多个独立数据库或服务,ACID 的边界就被打破了。
二、CAP:分布式系统的三角约束
CAP 理论指出,在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三者不可同时满足。由于网络分区在分布式系统中不可避免,实际架构通常是在 C 和 A 之间做取舍:
| 组合 | 含义 | 金融场景示例 |
|---|---|---|
| CA | 放弃分区容错,强一致且高可用 | 单机房单库核心账务,但无法跨机房容灾 |
| CP | 放弃可用性,保证强一致 | 支付清算、账务核心,分区时拒绝写入 |
| AP | 放弃强一致,保证可用性 | 营销活动、积分查询,允许短暂不一致 |
需要强调的是,CAP 中的 C 是线性一致性,而非 ACID 中的业务一致性。金融系统常说的“最终一致”,其实是在 AP 基础上通过补偿、对账、重试等手段逼近业务一致性。
三、BASE:柔性事务的实践哲学
BASE 是对 CAP 中 AP 的延伸,包含三个关键词:
- Basically Available(基本可用):允许损失部分可用性,例如降级、限流、排队。
- Soft state(软状态):允许中间状态存在,例如“转账中”“待清算”。
- Eventually consistent(最终一致):经过一段时间后,数据最终达到一致。
金融系统并非全部追求强一致。核心账务通常要求强一致,而支付通知、积分、风控画像等场景可以接受最终一致。BASE 为 Saga、TCC、Outbox 等柔性事务模式提供了理论支撑。
四、本地事务与分布式事务的本质区别
本地事务依赖单一数据库的日志和锁机制,回滚是数据库内部行为,开发者只需调用 commit 或 rollback。分布式事务则跨越多个资源管理器,没有全局锁,也没有统一的日志,必须引入协调者、补偿逻辑或消息中间件。
-- 本地事务:单库转账,数据库保证原子性
BEGIN;
UPDATE account SET balance = balance - 100 WHERE user_id = 'A';
UPDATE account SET balance = balance + 100 WHERE user_id = 'B';
COMMIT;
-- 分布式事务:跨服务转账,需引入 Saga/TCC/Outbox
-- 步骤1:账户服务扣款(本地事务)
-- 步骤2:账务服务入账(本地事务)
-- 步骤3:若步骤2失败,触发补偿:账户服务回滚扣款
关键差异可以归纳为三点:
- 一致性边界不同:本地事务在单库内保证强一致;分布式事务只能追求最终一致或业务级一致。
- 失败处理不同:本地事务自动回滚;分布式事务需要显式补偿、重试、幂等和对账。
- 隔离性不同:分布式事务难以实现全局隔离,中间状态可能被其他事务看到。
五、金融场景下的一致性要求
金融系统对一致性的要求并非一刀切,而是分层分级:
- 核心账务:强一致,借贷必须平衡,余额不能透支,通常采用 CP 架构或 TCC。
- 支付交易:最终一致,允许短暂“支付中”,通过状态机和对账保证结果正确。
- 营销积分:基本可用,允许延迟到账,采用 Outbox + 消息队列异步处理。
- 风控画像:软状态,允许分钟级延迟,优先保证高可用。
理解 ACID、CAP、BASE,是选择分布式事务方案的前提。本地事务靠数据库,分布式事务靠架构。金融系统的一致性要求,最终要落到业务容忍度、资金安全和可对账性上。