【问题标题】:How should I run compensations/rollback steps for a Saga Orchestration with Axon Framework?我应该如何使用 Axon 框架为 Saga 编排运行补偿/回滚步骤?
【发布时间】:2020-09-17 04:12:52
【问题描述】:

对于我想使用 Axon 为几个服务实现 Saga 编排的用例,我已经构建了:

  • order-service(具有 Spring boot + Axon Framework 的传奇编排器)
  • 支付服务(微服务)
  • 运输服务(微服务)

然后我有一个用 @Saga 注释的类,带有 3 个步骤/事件处理程序:

  • 已创建订单(首次服务)
  • 付款完成(第二次服务)
  • 订单发货(第三次服务)
  • 订单已有效创建

我的问题是我应该如何回滚/补偿之前执行的所有步骤,例如,如果运输服务失败?

从文档中我有一些疑问:

  • 我需要用@Saga 创建一个新类吗?
  • 失败的服务上我应该抛出异常还是将错误发送到另一个命令/事件
  • 我应该怎么打电话给SagaLifecycle.end()

如果有一个显示一些代码的解决方案会很棒。谢谢!

【问题讨论】:

  • 如果有一个显示一些代码的解决方案会很棒。谢谢! - 有一个显示一些代码的问题会很棒...... :)

标签: spring-boot microservices axon saga


【解决方案1】:

一个实施良好的 Saga 可以处理 Saga 管理的事务中出现的任何错误场景。因此,在从 saga 中调度的 任何 操作时,您应该能够预料到您会做出反应的例外情况。 这个反应是你正在寻找的补偿动作。

现在,为您解答具体问题:

我需要用@Saga 创建一个新类吗?

非常有信心,您不需要新的传奇来解决您域中的异常情况。所以没有。

在失败的服务上我应该抛出异常还是将错误发送到另一个命令/事件

我会在这里遇到异常或事件,而不是命令(因为(Axon)Saga 不处理命令)。是否走哪条路线取决于事件是否是有价值的业务事件,因此需要无限期地存储在事件中。然而,使用事件将意味着您将 Saga 的容错行为拆分为不同的 saga 事件处理程序,我个人不喜欢这样。因此,我更喜欢从要由 saga 处理的服务之一中抛出异常。随后,如果您需要存储异常发生,只需在其旁边发布一个事件即可。

我应该如何调用 SagaLifecycle.end()

说实话,不确定您在寻找这个问题的什么。 一旦 Saga 的生命周期结束,就应该调用 SagaLifecycle.end()。因此,当该事务完成时。 何时完成完全取决于您的域,并注意您需要调度补偿操作这一事实所必需的东西。

为了澄清我的意图,这里有一些(伪)代码显示我将在哪里执行补偿操作:

private transient CommandGateway commandGateway;

@SagaEventHandler(assocationProperty = "some-association)
public void on(SomeEvent event) {
    // Validate/set state if necessary
    commandGateway.send(new SomeCommand(...))
                  .exceptionally(exception -> {
                      // Dispatch compensating action through service/CommandGateway
                  });
}

【讨论】:

  • 看起来像 exceptionly() 做的工作。关于结束 SagaLifecycle,是我不确定如何在单个或多个 saga 类中使用补偿。谢谢
  • 您能详细说明为什么exceptionally() 不起作用吗?这对我来说目前还不清楚。确切地说,我说的是这种方法:docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
猜你喜欢
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2020-01-20
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多