一、本章前言
在单体应用架构中,开发者可依托数据库原生ACID事务,轻松保障业务数据的一致性、可靠性,事务开发简单且无需复杂协调。但微服务架构采用服务拆分、数据私有化、多库独立部署的核心设计,传统单体事务、经典分布式事务方案完全失效,跨服务业务流程极易出现数据不一致问题。
本章作为微服务事务治理的核心章节,针对性解决微服务分布式事务痛点,系统讲解了Saga模式的诞生背景、核心原理、两种实现模式、隔离性缺陷及工程解决方案,是落地微服务最终一致性事务的核心理论依据,也是微服务架构设计的必备知识点。
二、微服务架构下的事务困境
2.1 单体事务与微服务事务的核心差异
单体应用的所有业务数据统一存储在单一数据库,依托Spring事务注解等原生能力,即可实现完整的ACID事务特性,保证原子性、一致性、隔离性与持久性。无论下单、支付、退款等复杂串联业务,单库事务都能实现要么全部成功、要么全部回滚,数据一致性极强。
而微服务架构遵循一服务一数据库、数据私有不可见的设计原则,核心业务流程往往需要联动订单、用户、后厨、账务等多个独立服务,跨多数据库完成数据更新。以书中createOrder()下单流程为例,一次下单操作同时读写 4 个服务的数据,如图 4-1 所示:
这种跨服务、跨数据源的业务场景,彻底打破了单库 ACID 事务的适用边界,传统事务机制完全无法生效,亟需全新的分布式事务解决方案。
2.2 传统分布式事务(XA/2PC)被淘汰的核心原因
在微服务架构普及前,行业依托X/Open XA协议、两阶段提交(2PC)实现分布式事务,但本书明确指出,该方案完全不适用于现代微服务架构,核心缺陷集中在四点:
1. 技术栈兼容性极低:XA协议仅适配传统关系型数据库,无法兼容微服务主流的NoSQL数据库(MongoDB、Cassandra)、消息中间件(RabbitMQ、Kafka),使用该协议需要舍弃主流技术栈,实用性极差。
2. 系统可用性严重受损:2PC是同步阻塞事务机制,事务所有参与服务必须全部正常可用,才能完成事务提交。微服务业务链路越长、参与服务越多,系统整体可用性越低,与微服务高可用、高容错的核心设计目标相悖。
3. 与CAP理论取舍冲突:分布式系统遵循CAP理论,无法同时满足一致性、可用性、分区容错性。现代微服务优先保障可用性与分区容错性,接受数据最终一致性;而XA/2PC追求强一致性,架构设计理念完全冲突。
4. 不符合实际业务场景:绝大多数互联网核心业务(下单、转账、退款、履约)本身无需实时强一致,仅需最终一致性即可满足业务需求,2PC的强一致设计属于过度设计,冗余且低效。
2.3 Saga模式核心定义与核心特性
为彻底解决微服务跨服务事务一致性问题,本书正式引入Saga模式,这也是目前微服务实现最终一致性事务的标准、主流解决方案。
官方标准定义:Saga是一组由异步消息协调的本地事务序列,核心设计思路是拆分大而全的跨服务分布式事务,拆解为多个独立的单服务本地ACID事务,通过异步通信联动,最终实现分布式场景下的数据最终一致性。
核心特性(ACD特性):Saga模式舍弃了ACID中的隔离性(I),仅保留原子性(A)、一致性(C)、持久性(D)。隔离性的缺失是Saga模式所有优缺点、业务适配场景、并发问题及解决方案的核心根源。
核心补偿机制:与传统事务自动回滚不同,Saga 的每一步本地事务执行后都会直接提交、持久化数据,无法自动回滚。若后续任意事务步骤执行失败,系统必须执行手动编写的补偿事务,逆序撤销此前所有已提交的业务操作,以此保障数据最终一致,补偿执行逻辑如图 4-3 所示:
2.4 经典案例:FTGO下单Saga流程深度解析
本书以 FTGO 项目外卖下单业务为典型案例,完整演示 Saga 模式的完整执行链路,一次完整的下单事务,拆解为 6 个串联的本地事务,横跨订单、用户、后厨、账务四大核心服务,流程清晰且具备极强的业务参考性,整体事务拆分结构如图 4-2 所示:
正常执行流程:
1. 订单服务:创建状态为待审批(APPROVAL_PENDING)的订单数据;
2. 用户服务:校验用户身份、下单资质及账户状态;
3. 后厨服务:校验订单合规性,创建待处理后厨工单;
4. 账务服务:对用户绑定的信用卡进行额度授权锁定;
5. 后厨服务:更新后厨工单状态为待确认,准备履约;
6. 订单服务:更新订单状态为已审批(APPROVED),下单流程完成。
异常故障处理逻辑:Saga 的核心容错机制为逆序补偿,若流程中任意步骤执行失败,系统会从失败节点开始,反向执行所有前置事务的补偿逻辑。例如信用卡额度授权失败,系统会依次撤销后厨工单、取消待审批订单,清空本次事务所有数据变更,保证数据无残留、无不一致。同时书本明确规范:只读校验类步骤无需设计补偿逻辑,核心不可逆步骤执行后的后续事务,需设计为可成功、可重复执行的事务。
完整下单 Saga 每一步对应的补偿事务如下表 4-1 所示:
三、Saga两种核心协调模式
Saga模式的核心落地难点并非事务拆分,而是多步骤本地事务的有序调度、异常协调。书中明确划分了Saga的两种唯一落地实现模式,二者核心差异为「是否存在中心化调度控制器」,适配不同业务场景。
3.1 协同式Saga(事件驱动型)
核心原理:无中心协调组件,所有微服务地位平等、独立自治,全程基于事件发布 - 订阅机制联动。每个服务完成自身本地事务后,主动发布业务事件,下游订阅服务监听事件并触发自身下一步事务执行,依靠事件流转驱动完整 Saga 流程。以 FTGO 下单业务为例,完整事件驱动流程如图 4-4 所示:
上文图 4-4 展示了下单 Saga 正常执行的事件流转流程,而当流程出现故障时,协同式 Saga 依靠事件同样能驱动补偿流程完成数据回滚。以信用卡授权失败场景为例,完整补偿事件链路如图 4-5 所示:
账务服务检测信用卡授权失败后,发布Credit card authorization failed失败事件;后厨服务订阅该事件,执行rejectTicket()补偿逻辑撤销工单;工单撤销完成后发布对应事件,订单服务订阅事件执行rejectOrder(),取消待审批订单,完成整条 Saga 事务的逆序补偿。
核心优势:架构轻量化、无中心化依赖、服务彻底松耦合,代码开发简单,适配步骤少、链路短的简单业务流程。
核心缺陷:整体事务流程碎片化分散在各个服务代码中,无统一入口管控,业务链路难以梳理、问题难以排查、后期维护成本极高;多服务互相订阅事件易形成循环依赖,违背微服务解耦设计初衷;业务迭代升级时,需同步修改多个关联服务代码,扩展性极差。
3.2 编排式Saga(中心调度型)
核心原理:引入独立的 Saga 编排器作为中心化控制器,统一负责整个分布式事务的定义、调度、监控、异常处理。基于命令 / 回复消息的编排式整体架构如图 4-6 所示。编排器通过命令式消息主动调用各服务执行本地事务,接收服务执行结果,自动判断下一步执行流程,或触发全局补偿事务。
核心设计亮点:书中提出将编排器建模为状态机,完整固化正常执行流程、异常分支流程、故障补偿流程,完整下单 Saga 状态机流转模型如图 4-7 所示。所有事务状态支持持久化存储,具备可追溯、可复盘、可重试、可测试的特性,彻底解决协同式Saga流程混乱的问题。
核心优势:彻底规避服务循环依赖,业务解耦度更高;事务流程集中统一管控,链路清晰;故障定位、问题排查效率高;完美适配步骤多、链路长、逻辑复杂的核心业务流程。
唯一弊端:存在中心化组件,若架构设计不合理,会导致核心业务逻辑全部堆积在编排器中,形成“编排器臃肿、业务服务单薄”的不良架构。
原文权威选型结论:简单短流程、低复杂度业务可采用协同式Saga;企业级复杂核心业务、长链路事务,优先使用编排式Saga,这也是目前生产环境的主流选型。
基于 Eventuate Tram 框架实现创建订单 Saga 时,服务内部各核心组件存在固定调用时序,从 OrderService 初始化 Saga 状态、发起命令消息到持久化 Saga 实例全流程交互时序如图 4-13 所示。
工程落地场景中常使用 Eventuate Tram 框架实现编排式 Saga,该框架封装了编排器、消息分发、Saga 状态持久化等底层能力,框架内部核心组件结构如图 4-12 所示。
四、Saga隔离性缺陷与工程解决方案
本书将Saga缺失隔离性引发的并发问题定义为落地Saga模式的最大难点。由于Saga无事务隔离机制,多事务并发执行时会出现各类数据异常,书本针对性给出了标准化、可落地的解决方案,是规避生产事故的核心知识点。
4.1 无隔离性引发的三类核心数据异常
1.丢失更新:一个Saga事务尚未执行完毕、数据未最终敲定,另一个并发事务直接覆盖其已提交的临时数据,导致前序事务的数据更新丢失,引发数据错乱。
2.脏读问题:事务读取到其他未完成Saga事务的临时中间数据,并基于该非最终数据执行业务逻辑,最终导致业务出错、数据不一致。
3.不可重复读:同一个Saga事务的不同执行步骤中,多次读取同一业务数据,得到不同的数据结果,导致事务内部逻辑混乱、执行异常。
4.2 六大工业级落地对策
书中提供6种纯应用层解决方案,无需修改数据库底层机制,即可有效规避隔离性缺失带来的并发问题,适配绝大多数微服务业务场景:
1. 语义锁(核心常用方案):通过自定义业务状态字段(待处理、已审批、已取消、已完成等)实现应用层锁机制。标记处于事务处理中的数据,禁止其他并发事务读取、篡改,模拟ACID事务的隔离效果,广泛应用于订单、支付等核心业务。
2. 交换式更新:摒弃直接覆盖数据的更新方式,将数据修改改为可颠倒、可回溯的加减流水操作(如账户额度增减、库存变动流水),彻底避免并发覆盖导致的数据丢失问题。
3. 悲观视图:优化Saga事务的步骤编排顺序,将高风险、易出错的读操作后置执行,最大程度减少脏读带来的业务损失,降低并发异常概率。
4. 重读值(乐观锁机制):在执行数据更新操作前,重新读取数据库最新数据,校验数据是否被并发修改。若数据已变更,则终止当前事务并触发补偿,杜绝丢失更新问题。
5. 版本文件:记录所有业务操作流水与请求日志,对异步通信中乱序到达的请求进行重新排序、规整执行,解决微服务异步消息乱序引发的事务异常。
6. 业务风险评级:基于业务风险等级动态适配事务方案,普通低风险业务采用Saga最终一致性方案,大额资金、核心交易等高风险业务可兼容传统强一致事务,平衡系统可用性与数据安全性。
4.3 Saga事务三级分类模型
为标准化补偿事务设计、规范事务流程,书本将所有Saga事务步骤划分为三类,分类标准示意如图 4-8 所示:
是Saga落地的基础设计准则:
1.可补偿事务:事务流程前期的可撤销操作,业务上支持回滚,必须配套开发对应的补偿事务,保障异常时可反向撤销。
2.关键性事务:整个Saga流程的核心分水岭,该事务执行成功后,业务流程不可逆、无法回滚,无对应补偿逻辑,是事务状态切换的关键节点。
3.可重复性事务:关键性事务之后的后续步骤,业务设计上保证必然执行成功、支持幂等重试,无需设计补偿事务。
五、Saga工程落地架构
本章结合Eventuate Tram框架,给出了标准化、可落地的Saga微服务架构,明确四大核心组件的职责分工,为代码落地提供了清晰规范:
1.领域服务:承载核心业务逻辑,负责创建业务数据、初始化Saga事务流程,是业务执行的载体。
2.Saga编排器:通过DSL语法定义状态机,固化所有正常流程、异常分支、补偿流程,统一调度全链路事务执行。
3.Saga状态类:持久化存储Saga事务的运行状态、业务参数、执行轨迹,保障事务可续跑、可追溯、可重试。
4.命令处理器:作为服务与编排器的通信入口,接收中心化调度指令,执行本地事务并返回执行结果。
同时书本着重强调核心工程规范:必须使用事务性消息,保证数据库数据更新与消息发送的原子性,彻底杜绝消息丢失、数据与事务状态不一致的问题。
六、本章总结
1. 微服务多库拆分的架构特性,导致传统ACID事务、XA/2PC分布式事务完全失效,2PC因低可用、兼容性差、过度设计的缺陷,已不适用于现代微服务架构。
2. Saga模式是微服务实现分布式数据最终一致性的最优方案,核心思想为事务拆分+本地ACID执行+异步消息协调+异常补偿回滚,适配绝大多数微服务业务场景。
3. Saga分为协同式与编排式两种实现,协同式轻量化但维护性差,编排式集中可控、稳定性强,是企业级生产环境的主流选型。
4. Saga的核心短板是缺失事务隔离性,会引发丢失更新、脏读、不可重复读三类并发问题,需通过语义锁、乐观锁等六种应用层方案规避。
5. 工程落地需严格遵循事务三级分类规范,合理设计补偿事务、依托状态机管控流程、使用事务性消息,保障分布式事务稳定可靠。
七、拓展思考
书中原生依托的Eventuate Tram框架较为老旧,当下主流开发已大幅简化Saga落地成本。Spring Cloud生态可直接使用Seata Saga快速实现事务编排,云原生跨语言场景可选用Temporal框架,主流框架均已内置状态机管理、事务消息、隔离控制能力,开发者无需手动实现复杂的补偿与并发控制逻辑,可直接复用书本Saga核心设计思想,高效落地生产级分布式事务。