分布式事务核心原理与主流模型学习

一、Seata AT 模式(自动补偿型)

🔍 核心原理

  • 本质改进型两阶段提交(2PC) ,但将协调逻辑下沉到 数据源代理层,避免传统 2PC 的阻塞问题。
  • 关键机制
    1. 第一阶段(Prepare)
      • 执行业务 SQL(如 UPDATE account SET balance = 100
      • Seata 的 DataSourceProxy 自动解析 SQL,生成 before image(修改前快照)after image
      • undo log 与业务数据 在同一个本地事务中提交(保证原子性)
    2. 第二阶段(Commit / Rollback)
      • Commit:异步删除 undo log(无实际操作,快速完成)
      • Rollback :利用 before image 自动生成反向 SQL (如 UPDATE account SET balance = old_value WHERE id = ?)执行回滚

关键创新第一阶段就提交本地事务,不持有 DB 锁,极大提升并发能力(相比传统 2PC)。

⚖️ 优点

  • 对业务零侵入 :只需加 @GlobalTransactional 注解
  • 自动回滚:无需开发者写补偿逻辑
  • 支持主流 ORM(MyBatis、JPA)和微服务框架(Spring Cloud、Dubbo)

⚠️ 缺点

  • 仅支持关系型数据库(需能解析 SQL 生成 undo log)
  • 隔离性弱:第一阶段提交后,其他事务可读到"中间状态"(需配合全局锁或业务设计规避脏读)
  • 长事务风险:若全局事务长时间未决,undo log 无法清理,可能影响 GC 或存储
  • 性能损耗:额外写 undo log,TPS 下降约 10%~30%

"Seata AT 模式通过 代理数据源 + undo log 实现了自动补偿。它在第一阶段就提交本地事务,避免了传统 2PC 的同步阻塞,但牺牲了部分隔离性。适用于短事务、强一致要求、且全链路使用关系型数据库的场景,比如订单创建与库存扣减。"

二、RocketMQ 事务消息(最终一致性)

🔍 核心原理

  • 核心思想将分布式事务转化为"本地事务 + 异步消息"的组合 ,通过 Half Message + 状态回查 保证原子性。
  • 关键流程
    1. Producer 发送 Half Message(对 Consumer 不可见)
    2. 执行 本地事务(如写订单表)
    3. 根据本地事务结果:
      • 成功 → 向 Broker 发送 Commit,消息对消费者可见
      • 失败 → 发送 Rollback,消息丢弃
    4. Broker 回查机制 :若未收到 Commit/Rollback,Broker 会定时回调 Producer 的 checkLocalTransaction() 方法,查询本地事务状态

关键保障Half Message 与本地事务的原子性 由"先写 Half Message 再执行本地事务" + "回查兜底"共同保证。

⚖️ 优点

  • 高性能、高吞吐:消息异步解耦,不阻塞主链路
  • 天然支持失败重试、死信队列、流量削峰
  • 与业务完全解耦,适合非核心链路

⚠️ 缺点

  • 只能保证最终一致性(通常秒级延迟)
  • 必须处理消息重复消费(Consumer 需幂等)
  • 依赖消息中间件可靠性(如 RocketMQ 集群高可用)
  • 无法回滚已发送的消息(一旦 Commit,只能靠补偿)

"我们通过 RocketMQ 事务消息实现最终一致性:先发 Half Message,再执行本地事务,最后 Commit。即使应用崩溃,Broker 也会回查本地状态。这种方式把强一致需求转化为'本地事务 + 幂等消费',在用户注册送券、订单通知等场景中,既保证了可靠性,又避免了分布式事务的性能开销。"

三、TCC(Try-Confirm-Cancel)

🔍 核心原理

  • 核心思想将分布式事务拆解为三个业务方法 ,由开发者显式控制资源状态:
    • Try :尝试执行,预留资源 (如冻结库存、预占额度)→ 不真正消耗资源
    • Confirm :确认执行,真正消耗资源 (如扣减库存)→ 幂等、可重试
    • Cancel :取消执行,释放预留资源 (如解冻)→ 幂等、可重试

关键点Try 阶段成功后,后续 Confirm/Cancel 必须成功(通过重试 + 幂等保证)。

⚖️ 优点

  • 高性能:Try 完成后即可释放 DB 连接,无长锁
  • 业务语义精准:可实现"冻结-扣减"等复杂资源控制
  • 强一致性(业务层面)

⚠️ 缺点

  • 开发成本高:需编写三套逻辑
  • 三大陷阱必须处理
    1. 幂等性:Confirm/Cancel 可能被多次调用
    2. 空回滚:Cancel 在 Try 之前执行(如超时触发 Cancel,但 Try 未完成)
    3. 悬挂:Try 在 Cancel 之后执行(如网络延迟导致 Try 晚到)
  • 对业务侵入性强

"TCC 的本质是 业务层面的两阶段提交。我们在电商下单中用它实现库存预占:Try 冻结库存,Confirm 扣减,Cancel 解冻。虽然开发复杂,但它避免了 Seata AT 的锁表问题,在大促高并发下表现更稳。我们通过 Redis 记录 TCC 事务状态,解决了空回滚和悬挂问题。"


📊 三大模型核心对比(面试速记表)

维度 Seata AT RocketMQ 事务消息 TCC
一致性级别 强一致 最终一致 强一致(业务级)
核心原理 代理数据源 + undo log 自动回滚 Half Message + 本地事务 + 回查 业务三阶段(Try/Confirm/Cancel)
是否侵入业务 否(注解驱动) 否(但需幂等) 是(需写三套逻辑)
性能 中(有 undo log 开销) ⭐⭐⭐⭐⭐(异步) ⭐⭐⭐⭐(无长锁)
适用数据源 仅关系型数据库 任意 任意
最大风险 脏读、长事务 消息重复、延迟 空回滚、悬挂、开发复杂
典型场景 订单+库存(短事务) 通知、日志、营销 库存预占、金融交易

💡 高级面试加分认知

  1. "能不用分布式事务就不用"是第一原则

    → 优先通过 业务设计(如状态机、对账、重试)规避。

  2. 最终一致性是互联网系统的常态

    → 强一致只用于 资金、库存等核心资源,其余用 MQ + 幂等。

  3. Seata AT 不是万能的

    → 长事务、跨 NoSQL、高并发场景慎用。

  4. TCC 的难点不在逻辑,而在异常处理

    → 空回滚、悬挂、幂等才是落地关键。

  5. 所有分布式事务都需要"兜底"

    → 无论哪种模型,都要有 对账任务 + 人工干预通道


✅ 总结

  • Seata AT自动回滚,简单但有锁
  • RocketMQ 事务消息异步解耦,最终一致
  • TCC业务可控,高性能但复杂

单机数据库靠 本地事务(ACID) 保证一致性;

分布式系统因 数据分片 + 服务拆分 ,无法用本地事务跨节点协调 → 需要 分布式事务模型

但根据 CAP 定理 ,强一致(C)与高可用(A)不可兼得,因此所有模型都是 在一致性、性能、复杂度之间做权衡

相关推荐
Java 码农30 分钟前
RabbitMQ集群部署方案及配置指南04
分布式·rabbitmq
独自破碎E40 分钟前
在RabbitMQ中,怎么确保消息不会丢失?
分布式·rabbitmq
Java 码农42 分钟前
RabbitMQ集群部署方案及配置指南02
分布式·rabbitmq
虫小宝1 小时前
京东返利app分布式追踪系统:基于SkyWalking的全链路问题定位
分布式·skywalking
星图易码1 小时前
星图云开发者平台功能详解 | IoT物联网平台:工业设备全链路智能管控中枢
分布式·物联网·低代码·低代码平台
王五周八1 小时前
基于 Redis+Redisson 实现分布式高可用编码生成器
数据库·redis·分布式
成为你的宁宁1 小时前
【Zabbix 分布式监控实战指南(附图文教程):Server/Proxy/Agent 三者关系解析 + Proxy 部署、Agent 接入及取数路径验证】
分布式·zabbix
无心水1 小时前
【分布式利器:腾讯TSF】6、TSF可观测性体系建设实战:Java全链路Metrics+Tracing+Logging落地
java·分布式·架构·wpf·分布式利器·腾讯tsf·分布式利器:腾讯tsf
予枫的编程笔记2 小时前
Elasticsearch聚合分析与大规模数据处理:解锁超越搜索的进阶能力
java·大数据·人工智能·分布式·后端·elasticsearch·全文检索
sww_10262 小时前
Kafka和RocketMQ存储模型对比
分布式·kafka·rocketmq