问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

5 张图带你了解分布式事务 Saga 模式中的状态机

创作时间:
作者:
@小白创作中心

5 张图带你了解分布式事务 Saga 模式中的状态机

引用
CSDN
1.
https://blog.csdn.net/m0_46995061/article/details/145632631

状态机在分布式系统中扮演着重要角色,特别是在处理复杂事务流程时。本文将深入探讨Seata中Saga模式的状态机实现,从基本概念到具体应用,帮助读者理解这一强大工具的工作原理和使用方法。

1. 状态机简介

状态机是一个数学模型,用于抽象工作中的运行状态和流转规则,通过协调相关信号来完成预先设定的操作。其核心概念包括:

  • 状态:状态机当前的状态标识
  • 状态转移:定义状态之间的转移路由
  • 动作(Action):状态转移需要的操作
  • 事件:触发操作的信号或口令

状态机通常应用于状态类型多、分支流程复杂、需要经过多个步骤才能达到最终状态的场景。

2. Saga模式

Saga模式是分布式事务中处理长事务的一种解决方案,其理论基础源于Hector & Kenneth在1987年发表的论文。在Saga模式中,如果部分分支事务已提交成功,而其中一个分支事务提交失败,状态机将触发所有已提交成功的分支事务进行回滚。

关键点:分支事务的提交和回滚逻辑需要由业务代码实现。

3. Saga实现

Seata中Saga模式基于状态机实现,使用时需要先绘制状态图,定义服务调用流程,并为每个节点配备补偿节点。以电商场景为例,涉及订单、账户、库存三个分支事务:

分支事务
动作
状态
订单服务
保存订单
保存成功/失败
账户服务
扣减金额
扣减成功/失败
库存服务
扣减库存
扣减成功/失败

若任一分支事务提交失败,其他已成功事务需进行反向补偿。Seata状态机通过定义Json配置文件来实现这一过程,主要包括以下状态类型:

  • ServiceTask:对应分支事务的提交操作
  • Choice:用于流程选择
  • CompensationTrigger:触发补偿服务
  • Succeed:成功状态
  • Fail:失败状态

3.1 ServiceTask

以"保存订单"状态为例:

"SaveOrder": {
  "Type": "ServiceTask",
  "ServiceName": "orderSave",
  "ServiceMethod": "saveOrder",
  "CompensateState": "DeleteOrder",
  "Next": "ChoiceAccountState",
  "Input": [
    "$.[businessKey]",
    "$.[order]"
  ],
  "Output": {
    "SaveOrderResult": "$.#root"
  },
  "Status": {
    "#root == true": "SU",
    "#root == false": "FA",
    "$Exception{java.lang.Throwable}": "UN"
  },
  "Catch": [
    {
      "Exceptions": [
        "java.lang.Throwable"
      ],
      "Next": "CompensationTrigger"
    }
  ]
}

3.2 Choice

以"ChoiceAccountState"为例:

"ChoiceAccountState": {
  "Type": "Choice",
  "Choices": [
    {
      "Expression": "[SaveOrderResult] == true",
      "Next": "ReduceAccount"
    }
  ],
  "Default": "Fail"
}

3.3 Fail

当发生异常时,会跳转到CompensationTrigger:

"CompensationTrigger": {
  "Type": "CompensationTrigger",
  "Next": "Fail"
}

完整Json配置文件如下:

{
  "Name": "buyGoodsOnline",
  "Comment": "buy a goods on line, add order, deduct account, deduct storage ",
  "StartState": "SaveOrder",
  "Version": "0.0.1",
  "States": {
    // 各个状态的详细配置
  }
}

4. 状态机应用

电商案例中,三个分支服务分别定义了三个State,对应的ServiceMethod如下:

  • SaveOrder#saveOrder
  • ReduceAccount#decrease
  • ReduceStorage#decrease

状态机启动时需要传入参数:

StateMachineEngine stateMachineEngine = (StateMachineEngine) ApplicationContextUtils.getApplicationContext().getBean("stateMachineEngine");
Map<String, Object> startParams = new HashMap<>(3);
String businessKey = String.valueOf(System.currentTimeMillis());
startParams.put("businessKey", businessKey);
// 其他参数设置
StateMachineInstance inst = stateMachineEngine.startWithBusinessKey("buyGoodsOnline", null, businessKey, startParams);

5. 状态机原理

状态机的工作流程如下:

  1. 启动全局事务
  2. 记录状态机参数到本地数据库
  3. 注册分支事务到Seata Server
  4. 执行各状态并记录状态,通过EventQueue传递路由消息
  5. 最终提交或回滚全局事务

6. 高可用性

Seata状态机内嵌在应用中,上下文和执行日志存储在本地数据库,因此是无状态的。当应用宕机时,Seata Server会将恢复请求发送到存活实例,从数据库中恢复状态机上下文和执行日志。

7. 总结

本文详细介绍了Seata中Saga模式的状态机实现,从基本概念到具体应用,再到原理分析,为分布式系统开发提供了有价值的参考。状态机的设计思路和实现方式,不仅适用于Seata,也为其他场景下的状态机设计提供了有益的借鉴。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号