IIWAB

分布式事务全方案对比:XA、可靠消息、数据库AT、TCC、SAGA、

IIWAB 2月前 ⋅ 120 阅读

先做分类梳理:

  1. 强一致刚性事务:XA(2PC,数据库底层两阶段)
  2. 柔性最终一致
    • 基于数据库自动补偿:Seata AT(最常用,无侵入)
    • 业务手动预留补偿:TCC(Try-Confirm-Cancel)
    • 长流程逆向补偿:SAGA(状态机/事件驱动)
    • 异步解耦消息方案:可靠消息事务(本地消息表/RocketMQ事务消息、最大努力通知)
  3. Seata是框架载体,内置XA/AT/TCC/SAGA四种模式,不是独立事务模型。

一、各方案核心原理

1. XA(标准2PC,数据库层面强一致)

  • 规范:X/Open XA,TM事务管理器协调多个DB资源管理器RM
  • 两阶段:
    1. Prepare:各DB执行SQL、持有行锁不提交,返回就绪;任一失败全部回滚
    2. Commit/Rollback:全部就绪则统一提交,否则全部回滚
  • 一致性:强一致、完整ACID,中间无脏数据
  • 底层依赖:数据库原生XA驱动(MySQL、Oracle支持)

2. 基于消息的最终一致性(异步柔性)

分为两类:

(1)可靠消息事务(核心业务)

  • 两种实现:
    • 本地消息表:业务库新建msg表,业务操作+写入消息在同一本地事务,定时任务轮询发MQ;消费失败重试,消费成功标记消息完成
    • RocketMQ事务消息:半消息+本地事务回调,MQ内置状态存储,无需自建消息表
  • 核心:本地事务原子绑定消息发送,保证业务成功则消息必投;消费端幂等防重复

(2)最大努力通知(弱一致,非核心)

本地事务完成后循环重试推送通知,超过阈值人工兜底;无原子绑定,允许消息丢失,仅用于短信、回调通知。

3. 基于数据库的一致性:Seata AT(自动补偿,业务无侵入)

  • 一阶段:执行业务SQL,同步记录undo回滚日志,本地事务直接提交释放锁;全局锁标记行隔离脏写
  • 二阶段Commit:异步删除undo日志,快速结束
  • 二阶段Rollback:读取undo日志自动生成补偿SQL回滚数据
  • 本质:框架自动实现补偿事务,仅依赖关系型数据库,注解@GlobalTransactional即用

4. TCC(应用层三阶段手动补偿)

三段接口全部业务手动编码:

  1. Try:校验参数、冻结/预留资源(冻结库存、锁定余额),提交本地事务释放DB锁
  2. Confirm:全局成功,确认扣减预留资源(仅使用Try冻结数据)
  3. Cancel:全局失败,释放冻结资源
  • 特点:无全局长锁,支持Redis/Mongo等非DB资源,一致性感知最强的柔性方案

5. SAGA(长事务逆向补偿)

将长业务拆分为N个独立本地事务,每个正向操作对应反向补偿操作

  • 正向:T1→T2→T3依次提交本地事务(无资源锁定)
  • 失败补偿:若T3失败,逆序执行C3→C2→C1撤销已完成操作 两种实现:
  1. 编排式(Seata SAGA状态机):中心调度器定义流程、补偿逻辑
  2. 编排式(事件驱动):服务间通过MQ消息联动,无中心协调
  • 适用跨系统、长周期流程(下单→出库→物流→结算)

6. Seata说明

Apache Seata是分布式事务框架,统一TC事务协调器,同时封装4种模式:XA / AT / TCC / SAGA,一套框架切换不同一致性方案。

二、六大方案核心维度对比总表

对比维度XA(2PC)Seata AT(数据库自动补偿)TCCSAGA可靠消息事务(MQ)最大努力通知
一致性等级强一致(ACID)最终一致准强最终一致(Try锁定)最终一致最终一致弱最终一致
锁机制全局长锁,Prepare阶段持续阻塞一阶段释放DB锁,全局行锁防脏写Try阶段冻结业务资源,无DB长锁无任何锁,允许脏读无锁,完全异步无锁
性能并发极差,高并发阻塞中等,比XA强很多最优,高吞吐高吞吐,适合长流程极高,异步解耦极高
代码侵入极低,仅配置XA数据源极低,仅注解@GlobalTransactional极高,每个服务写3套接口中高,每个步骤写正向+补偿中,建消息表/适配事务MQ低,定时重试任务
数据库依赖必须支持XA协议仅支持关系型DB(MySQL/Oracle)无依赖,支持Redis/Mongo/第三方接口无依赖,任意存储/外部系统依赖MQ+关系库MQ即可
隔离性完美隔离,无脏读脏写存在脏写风险(全局锁规避)业务层隔离,无脏数据最差,大量中间脏数据可见中间态长期可见中间态长期可见
开发成本低,配置即用极低,业务零改造极高,幂等/空回滚/悬挂全手动处理中高,维护状态机+补偿逻辑中等,幂等、消息重试、死信最低,仅重试推送
故障风险协调者宕机导致锁阻塞死锁undo日志丢失会数据不一致业务编码错误易资损补偿逻辑出错不可逆MQ宕机丢失消息,消费重复消息丢失必须人工兜底
典型场景银行核心转账、低并发金融账务普通微服务电商订单、库存、积分高并发支付、库存扣减、Redis事务长流程:旅游预订、物流、跨企业审批订单发券、充值、异步库存扣减短信通知、支付回调、营销推送

三、优缺点深度拆解

1. XA(2PC)

优点

  • 数据库原生支持,应用零改造,标准ACID强一致
  • 无需业务写补偿逻辑,回滚完全自动 缺点
  • Prepare阶段长时间持有行锁,并发一高直接大量阻塞,性能灾难
  • 协调器TC宕机时,分支资源永久锁定,人工解锁成本高
  • 分库分表场景锁范围放大,死锁概率飙升 局限:只适合并发量小、资金绝对严谨的传统金融核心系统,互联网高并发业务基本淘汰。

2. Seata AT(最主流互联网方案)

优点

  • 无业务侵入,原有CRUD代码无需改动,接入成本极低
  • 一阶段释放DB锁,性能远超XA,适配绝大多数电商业务
  • Seata框架成熟,undo日志、全局锁、重试内置封装 缺点
  • 仅支持关系型数据库,无法对接Redis、第三方外部接口
  • 存在脏写问题(一阶段提交后其他事务可更新未回滚数据),需通过业务唯一索引/全局锁规避
  • 回滚依赖undo日志,日志损坏会造成数据不一致

3. TCC(高性能核心交易首选)

优点

  • 性能天花板:一阶段立刻释放数据库锁,无全局阻塞
  • 不绑定数据库,支持缓存、第三方支付、外部API参与分布式事务
  • Try资源冻结,业务层几乎不会出现中间脏数据,一致性可控 缺点
  • 侵入极强:每个分布式接口必须实现Try/Confirm/Cancel三套代码,代码量翻倍
  • 复杂边界问题全部手动处理:空回滚、业务悬挂、幂等、防重复Confirm/Cancel,极易出资损bug
  • 表结构常需改造(增加冻结字段、冻结库存数量)

4. SAGA(长流程、跨系统专用)

优点

  • 全程无锁,吞吐量最高,支持数小时/天级长事务
  • 兼容遗留系统、外部第三方服务(对方不提供TCC三接口)
  • 编排式状态机可视化流程,复杂业务流程易维护 缺点
  • 无隔离性,流程中途其他服务可读取到未完成脏数据
  • 不可逆业务(扣款、发货)补偿逻辑极难实现,补偿失败无法兜底
  • 流程越长,补偿链路越复杂,维护成本高

5. 可靠消息事务(异步解耦场景)

优点

  • 完全异步,主流程不阻塞,吞吐最高,削峰填谷
  • 服务高度解耦,订单、库存、积分可独立扩容迭代
  • 实现简单,本地消息表无框架依赖,轻量落地 缺点
  • 一致性延迟,中间态对用户可见,不能用于同步强一致业务
  • 必须处理重复消费、消息丢失、死信队列、定时校对
  • 主业务与消息表耦合,多业务需多张消息表

6. 最大努力通知(边缘通知场景)

优点:实现最简单,无需本地事务绑定消息 缺点:一致性最弱,存在消息永久丢失风险,核心资金业务严禁使用,仅做通知类弱同步。

四、选型决策指南(业务场景直接对照)

  1. 低并发、资金强一致、不能容忍中间脏数据 → XA(传统银行内网账务)
  2. 普通微服务、MySQL为主、不想改业务代码、中等并发 → Seata AT(90%互联网电商、后台管理系统)
  3. 高并发核心交易、Redis/第三方支付参与、追求极致性能 → TCC(秒杀库存、支付清算、账户余额)
  4. 超长业务流程、跨外部公司/遗留系统、步骤多周期长 → SAGA(酒店预订、物流履约、供应链审批)
  5. 主流程同步、下游可异步延迟执行、服务解耦 → 可靠消息事务(下单发优惠券、充值到账、异步统计)
  6. 仅做通知推送、允许短暂不一致、失败人工处理 → 最大努力通知(短信、营销推送、支付结果回调)

五、易混淆概念澄清

  1. Seata ≠ 独立事务方案 Seata是框架,AT/TCC/SAGA/XA是它提供的四种事务模式,选型先选模型,再用Seata落地。
  2. AT与XA都基于数据库,但底层逻辑完全不同 XA是数据库原生两阶段锁;AT是框架拦截SQL生成undo日志,一阶段直接提交本地事务,无长锁。
  3. TCC与SAGA补偿逻辑区别
  • TCC:事前预留冻结资源,Confirm才真正扣减,无脏数据;
  • SAGA:事前直接提交修改,失败再逆向撤销,全程可见脏数据。
  1. 可靠消息是异步柔性,XA/AT/TCC/SAGA默认同步执行 消息事务会将分布式事务拆成两段本地事务异步执行,其余方案整体同步阻塞。

全部评论: 0

    我有话说: