1. 概述
在微服务或多数据库系统中,业务操作往往跨多个系统或数据库执行,本地事务无法保证全局一致性。分布式事务方案旨在解决跨系统操作的一致性问题,保证数据最终一致或强一致。
分布式事务方案按实现方式主要分为以下几类:
- XA / 两阶段提交(2PC)
- 柔性事务 TCC(Try-Confirm-Cancel)
- Saga(可补偿事务)
- 本地事务表(Outbox / 可靠事件模式)
- 事务消息(半消息)
- CDC + Kafka(事件流驱动)
2. 主要方案与原理
2.1 XA / 两阶段提交(2PC)
原理:
-
协调者 + 参与者
-
事务分两阶段:
- Prepare:参与者准备提交,锁定资源
- Commit/Rollback:协调者根据所有参与者状态决定提交或回滚
优点:
- 强一致性(ACID)
- 开发简单(由驱动/中间件管理)
缺点:
- 性能差、阻塞资源
- 单点故障风险高
- 不适合高并发、跨异构系统
适用场景:
- 银行内部系统、低并发跨库事务
2.2 柔性事务 TCC(Try-Confirm-Cancel)
原理:
-
每个业务资源提供三个操作:
- Try:预留/冻结资源
- Confirm:提交资源操作
- Cancel:释放或回滚资源
优点:
- 最终一致性,可控
- 避免分布式锁
缺点:
- 业务侵入性大(每个资源需要三套接口)
- 状态复杂,幂等、空回滚需手动处理
适用场景:
- 库存冻结、账户余额冻结、票务/航班/酒店预订等关键资源
2.3 Saga(可补偿事务)
原理:
- 将长事务拆成多个本地事务
- 每个本地事务提供补偿动作
- 正向执行失败 → 按逆序执行补偿事务
执行模型:
- 编排式(Orchestration):由协调者控制顺序
- 舞蹈式(Choreography):各服务通过事件驱动下一步
优点:
- 无跨资源锁,性能高
- 适合长链路、事件驱动
- 业务可拆分、补偿清晰
缺点:
- 每步操作必须可补偿
- 补偿可能失败,需要幂等重试
- 不适合不可逆资源
适用场景:
- 电商下单链路、旅游预订、多步骤审批流程
2.4 本地事务表(Outbox / 可靠事件模式)
原理:
- 在本地数据库事务中同时写业务数据和 outbox 表
- 异步任务扫描 outbox,可靠投递消息到 MQ
- 投递成功后更新状态,失败重试
优点:
- 无跨资源锁,性能高
- 保证消息不丢失
- 实现简单,适用于大多数互联网业务
缺点:
- 只能实现最终一致性
- 轮询或任务调度增加系统复杂度
适用场景:
- 订单、库存、积分、消息事件投递
- MQ 不支持事务时
2.5 事务消息(半消息)
原理:
- 先发送“半消息”到 MQ(暂不可投递)
- 执行本地事务
- 本地事务成功 → 确认半消息投递
- 失败 → 删除半消息
- MQ 定期回查,保证消息最终投递或丢弃
优点:
- 消息与数据库绑定提交
- 最终一致性高,可靠性强
- 开发成本低,无需复杂补偿
缺点:
- 依赖 MQ(如 RocketMQ)
- 不适合所有消息中间件
适用场景:
- 下单成功必须通知库存/支付/物流
- 消息驱动业务,但不想使用 TCC/Saga
2.6 CDC + Kafka
原理:
- CDC(Change Data Capture)捕获数据库增删改操作
- 将变更事件写入 Kafka
- 下游系统消费事件,实现实时同步
优点:
- 无侵入,业务代码无需改动
- 高吞吐,支持多下游系统
- 实现最终一致性和事件驱动架构
缺点:
- 依赖基础设施(CDC + Kafka)
- 无法直接处理复杂业务逻辑,仅传递数据变化
适用场景:
- 实时数据同步到搜索、缓存、数据仓
- 事件驱动架构
- 替代 Outbox 扫描,提高性能
3. 核心对比表
| 方案 | 一致性 | 侵入性 | 性能 | 典型场景 |
|---|---|---|---|---|
| XA / 2PC | 强 | 低 | 最差 | 内部金融、低并发跨库 |
| TCC | 最终一致(可控) | 高 | 较高 | 冻结资源(库存/余额) |
| Saga | 最终一致 | 中 | 高 | 可补偿长链路业务 |
| Outbox | 最终一致 | 低 | 高 | 消息投递、订单事件 |
| 事务消息(半消息) | 最终一致 | 中 | 高 | MQ 驱动业务,可靠消息 |
| CDC + Kafka | 最终一致 | 很低 | 高 | 数据同步、事件流、EDA |
4. 总结与选型建议
- 需要强一致 → XA / 2PC
- 关键资源冻结 → TCC
- 可补偿长链路 → Saga
- 本地事务 + 消息投递 → Outbox / 事务消息
- 大规模实时事件流 → CDC + Kafka
工程选择原则:
- 资源可补偿 → Saga
- 资源需预留 → TCC
- 仅需消息可靠 → Outbox / 事务消息
- 数据同步与流处理 → CDC + Kafka