分布式事务方案总结文档

5 阅读4分钟

1. 概述

在微服务或多数据库系统中,业务操作往往跨多个系统或数据库执行,本地事务无法保证全局一致性。分布式事务方案旨在解决跨系统操作的一致性问题,保证数据最终一致或强一致。

分布式事务方案按实现方式主要分为以下几类:

  • XA / 两阶段提交(2PC)
  • 柔性事务 TCC(Try-Confirm-Cancel)
  • Saga(可补偿事务)
  • 本地事务表(Outbox / 可靠事件模式)
  • 事务消息(半消息)
  • CDC + Kafka(事件流驱动)

2. 主要方案与原理

2.1 XA / 两阶段提交(2PC)

原理:

  • 协调者 + 参与者

  • 事务分两阶段:

    1. Prepare:参与者准备提交,锁定资源
    2. Commit/Rollback:协调者根据所有参与者状态决定提交或回滚

优点:

  • 强一致性(ACID)
  • 开发简单(由驱动/中间件管理)

缺点:

  • 性能差、阻塞资源
  • 单点故障风险高
  • 不适合高并发、跨异构系统

适用场景:

  • 银行内部系统、低并发跨库事务

2.2 柔性事务 TCC(Try-Confirm-Cancel)

原理:

  • 每个业务资源提供三个操作:

    1. Try:预留/冻结资源
    2. Confirm:提交资源操作
    3. Cancel:释放或回滚资源

优点:

  • 最终一致性,可控
  • 避免分布式锁

缺点:

  • 业务侵入性大(每个资源需要三套接口)
  • 状态复杂,幂等、空回滚需手动处理

适用场景:

  • 库存冻结、账户余额冻结、票务/航班/酒店预订等关键资源

2.3 Saga(可补偿事务)

原理:

  • 将长事务拆成多个本地事务
  • 每个本地事务提供补偿动作
  • 正向执行失败 → 按逆序执行补偿事务

执行模型:

  1. 编排式(Orchestration):由协调者控制顺序
  2. 舞蹈式(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