找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4557

积分

0

好友

602

主题
发表于 17 小时前 | 查看: 4| 回复: 0

一、什么是分布式事务?

在现代微服务架构下,业务逻辑通常被拆分到多个独立的服务中。这带来了一个经典难题:当一个业务操作需要跨多个服务更新数据时,如何确保这些操作要么全部成功,要么全部失败?这就是分布式事务要解决的核心问题。

简单来说,分布式事务是指事务的参与者、资源服务器以及事务管理器分别位于不同的分布式节点之上。我们需要保证这些跨节点的操作具有原子性,从而维护全局数据的一致性。

一个典型的场景是电商下单:

  1. 订单服务:创建订单记录。
  2. 库存服务:扣减商品库存。
  3. 账户服务:从用户账户扣款。

这三个操作分属三个不同的服务和数据库,但它们必须作为一个整体(原子操作)来完成。如果创建订单成功,但扣减库存失败,整个交易就应该回滚,否则会导致数据不一致(有订单但没减库存)。

分布式事务典型架构(TM/TC模型)流程图

实现分布式事务,主要面临三大挑战:

  • 网络不确定性:服务间通信可能发生延迟、超时甚至彻底失败,如何判断对方的状态?
  • 节点故障:任意一个服务节点宕机,都可能导致整个事务“卡”在半路,状态不一致。
  • 性能瓶颈:跨网络的多次协调和资源锁定,必然会引入更高的延迟,影响系统吞吐量。

为了解决这些挑战,业界发展出了两大思路:刚性事务柔性事务


二、刚性事务 vs 柔性事务

1. 刚性事务

  • 理论基础:严格遵循 ACID(原子性、一致性、隔离性、持久性)原则。
  • 核心特点:追求强一致性。事务执行过程中会对涉及的资源加锁,参与者同步阻塞等待协调者的决策,隔离级别高。
  • 代表方案:基于 XA 协议 的两阶段提交(2PC)、三阶段提交(3PC)。
  • 优点:数据一致性最强,对业务代码侵入小。
  • 缺点:性能差(同步阻塞),可用性低(协调者单点故障),扩展性弱,不适合高并发和长事务场景。

2. 柔性事务

  • 理论基础:遵循 BASE(基本可用、软状态、最终一致性)理论。
  • 核心特点:放弃强一致性,接受短暂的数据不一致(软状态),通过补偿重试机制来达到最终一致性。通常不长期持有锁,并发度高。
  • 代表方案:TCC、Saga、本地消息表、事务消息、最大努力通知。
  • 优点:高性能、高可用、可扩展性好,非常适合微服务架构。
  • 缺点:对业务有侵入(如TCC需要实现三个接口),开发复杂度较高,需要仔细处理幂等和补偿逻辑。

简单来说,刚性事务像“强锁”,确保数据100%精确但牺牲了速度;柔性事务像“协议”,允许暂时的误差但换来了系统的敏捷与健壮。在当今高并发、高可用的互联网系统中,柔性事务是更主流的选择。


三、刚性事务解决方案

1. 两阶段提交(2PC)

2PC是最经典的分布式事务协议,像一个谨慎的“指挥官”。

  • 角色:一个事务协调者(TC) 和多个参与者(RM)
  • 过程
    1. 准备阶段(投票):协调者询问所有参与者:“可以提交吗?”参与者执行事务操作(写本地undo/redo日志),锁定资源,但不提交,然后回复“同意”或“中止”。
    2. 提交阶段(执行):如果所有参与者都同意,协调者发送“全局提交”命令;否则发送“全局回滚”命令。参与者收到命令后执行最终提交或回滚,并释放资源锁。
  • 缺点
    • 同步阻塞:在收到协调者指令前,参与者占用的资源锁不会释放,其他事务必须等待。
    • 单点故障:协调者一旦宕机,参与者会一直处于不确定的阻塞状态。
    • 数据不一致:在提交阶段,如果协调者发送部分提交指令后崩溃,会导致部分参与者提交,部分未提交。

2. 三阶段提交(3PC)

3PC是对2PC的改良,主要引入了超时机制,并将准备阶段一分为二。

  • 过程
    1. CanCommit:协调者询问参与者是否“具备提交条件”。此阶段仅做可行性检查,不锁定资源
    2. PreCommit:如果所有参与者都回复Yes,协调者发送“预提交”指令。参与者此时才执行事务并锁定资源,然后返回确认。
    3. DoCommit:协调者根据预提交阶段的响应,决定最终提交或中止。
  • 优点:降低了阻塞范围。在PreCommit阶段后,如果参与者收不到DoCommit指令,超时后可以自行提交,减少了长时间阻塞的风险。
  • 缺点:在网络分区故障下,仍可能出现数据不一致。实现更为复杂,在实际生产环境中应用相对较少。

四、柔性事务解决方案

1. TCC(Try-Confirm-Cancel)

TCC可以理解为“业务层面”的两阶段提交,需要开发者显式实现三个业务方法。

  • Try:资源检查和预留。例如:冻结库存、预扣账户余额(资金暂存于中间状态)。
  • Confirm:确认执行业务。使用Try阶段预留的资源完成最终操作,此操作必须幂等
  • Cancel:取消业务。释放Try阶段预留的资源,进行回滚,此操作也必须幂等

执行流程

  1. 主业务服务发起全局事务,依次调用所有从服务的Try接口。
  2. 若所有Try成功,则调用各服务的Confirm接口进行确认。
  3. 若任意一个Try失败,则调用所有已成功服务的Cancel接口进行补偿。

适用场景:对一致性要求较高且执行时间短的业务,如支付、下单。其缺点也很明显:业务侵入性高,每个服务都需要实现三个接口,设计和开发成本大。

2. Saga 模式

Saga模式将一个长的分布式事务拆分为多个连续的本地事务,并为每个本地事务设计一个对应的补偿事务

  • 协调方式
    • 编排(Choreography):事件驱动。每个服务执行完后,发布事件触发下一个服务;失败时,由监听器触发逆向补偿事件。无中心节点,但流程逻辑散落在各服务中。
    • 协同(Orchestration):指令驱动。一个中央协调器负责按顺序调用各服务,并在失败时调用对应的补偿服务。逻辑集中,易于管理和监控。
  • 优点:非常适合长事务、业务流程复杂的场景(如旅行预订:订票、订酒店、租车)。全程无锁,并发度高。
  • 缺点:事务隔离性弱(可能出现脏读),补偿逻辑的设计和实现同样复杂,也需要保证幂等性。

3. 本地消息表(最终一致性)

这是一种非常朴素而可靠的方案,核心是利用本地数据库事务来保证消息投递。

  • 原理
    1. 事务发起方在同一个本地数据库事务中,完成业务操作插入一条消息记录到本地消息表。
    2. 后台有一个定时任务,不断扫描本地消息表,将未发送的消息投递到消息队列。
    3. 消息消费者处理业务,成功后向MQ返回确认(ACK),发起方再删除本地消息。
    4. 若消费失败,MQ会重试,要求消费方实现幂等处理。
  • 优点:实现简单,可靠性高,保证了业务和消息的本地原子性。
  • 缺点:消息表与业务库耦合,会竞争数据库资源;定时扫描存在延迟;扩展性受数据库性能制约。

4. 事务消息(RocketMQ等)

这是对本地消息表的升级,将消息的持久化和状态管理职责转移给了消息中间件。

  • 原理(以RocketMQ为例)
    1. 生产者发送“半消息”到MQ(此消息对消费者不可见)。
    2. MQ返回成功响应后,生产者执行本地事务。
    3. 根据本地事务结果,生产者向MQ发送CommitRollback指令。
    4. 若MQ长时间未收到确认指令,会发起“事务回查”询问生产者本地事务的最终状态,以此决定消息是否投递。
  • 优点:业务方无需自建消息表,与业务数据库解耦。
  • 缺点:强依赖于消息中间件的事务消息特性,且实现逻辑相对复杂。

5. 最大努力通知

适用于对一致性要求最低的场景,目标不是保证“一定成功”,而是“尽最大努力”。

  • 原理:服务A完成操作后,异步调用服务B的接口进行通知。如果失败,则按照策略(如1min,5min,10min…)反复重试。接收方B需要提供幂等接口,并且通常还需要有主动查询补偿的机制。
  • 典型场景:支付结果回调通知、短信发送状态通知。
  • 优点:实现极其简单,对业务侵入小。
  • 缺点:无法保证数据的强一致或最终一致,业务方必须能接受通知可能永远失败的情况。

五、方案对比与选择建议

主流分布式事务方案核心特性对比表

如何选择?这里有几点实用的建议:

  • 追求高性能与高可用:如果你的业务可以接受秒级甚至分钟级的最终一致性,那么柔性事务是首选。其中,短事务、高性能场景(如支付)可选TCC;长流程、业务复杂的场景(如订单履约)可选Saga。
  • 业务天然异步:如果流程本身可以异步化,比如订单生成后发送短信或积分,使用事务消息(如RocketMQ)是优雅的解耦方案。
  • 系统简单,快速落地:对于中小型系统,不想引入复杂的中间件,本地消息表是经过验证的、简单可靠的方案。
  • 强一致性是铁律:只有在像跨行转账这种对强一致性有绝对要求,且并发量不高的场景下,才值得考虑2PC/3PC,并承受其带来的性能代价。

没有“银弹”,每种方案都是在一致性、性能、复杂度和可用性之间做权衡。在实际架构设计中,深入理解业务需求是做出正确技术选型的第一步。如果你想更深入地探讨特定方案在Java微服务中的实现细节,或者与其他开发者交流实战经验,欢迎来云栈社区的相关板块一起学习成长。




上一篇:程序员如何破局35岁焦虑?从写代码到写知识,打造个人知识杠杆
下一篇:LLM编程助手为何产生“幻觉”?解析AI编程的底层机制与应对策略
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-24 22:34 , Processed in 0.673899 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表