当前位置: 首页 > 知识库问答 >
问题:

我应该如何使用Axon框架为Saga编排运行补偿/回滚步骤?

丰博
2023-03-14

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

  • 订单服务(带有Spring boot Axon框架的saga orchestrator)
  • 支付服务(微服务)
  • 运输服务(微服务)

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

  • 订单已创建(首次服务)

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

从留档我有一些疑问:

  • 我需要用@Saga创建一个新类吗
  • 在失败的服务上,我应该引发异常还是将错误发送到另一个命令/事件
  • 我应该如何调用SagaLifecycle。end()

如果有一个显示一些代码的解决方案,那就太好了。谢谢!

共有1个答案

东门令
2023-03-14

一个实施良好的佐贺可以处理佐贺所管理的事务中出现的任何错误场景。因此,在从传奇内部调度任何操作时,您应该能够预料到一个例外情况,您将对此做出反应。正是这种反应才是你想要的补偿作用。

现在,为了回答你的确切问题:

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

我很有信心,你不需要一个新的传奇来解决你所在领域的例外情况。所以没有。

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

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

我应该如何称呼SagaLifecycle.end()

老实说,我不确定你想问这个问题。萨伽利夫循环。一旦传奇的生命周期结束,应该调用end()。因此,当该事务完成时。当它完成时,完全取决于您的领域,并注意到一些必要的事实,您需要调度一个补偿动作。

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

java prettyprint-override">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
                  });
}
 类似资料:
  • 您可以在下面看到我的示例类。 基本上,我希望使用Axon的表来存储事件,并使用我自己的实体表来存储实体。我知道,如果我激发在聚合中处理的,将发布一个事件,之后它将转到,Axon将在其表中持久化该事件。 如何回滚表,还是应该为此使用补偿事件? 我的外部@EventHandler类:

  • null 我的问题是,有没有人用Axon做过类似的事情,有补偿,最好的做法是什么?如何重试Saga过程?用RetryScheduler?如果可以的话,添加一个github回购。 谢谢,Máté

  • 中的任何提示都非常感谢,谢谢。

  • 让我们举一个电子邮件传奇的例子:当一个用户注册时,我们创建一个发布UserRegisterEvent的用户聚合,一个传奇将被创建,这个传奇负责确保注册电子邮件被发送给用户(电子邮件可能包含验证密钥、欢迎消息等)。 我们是否应该使用: > 用try/catch->缩放吗? 使用deadline是因为我们只使用“send”,而不处理命令的最终错误,这可能是发送失败(其他服务关闭,等等) 其它的呢? 还

  • 任何关于如何做到这一点的文件都将不胜感激。 提前谢了。

  • 我想要的 我在寻找在Activiti上下文达到等待状态之前回滚它的方法。例如,我有: 真是个问题: 我不想手动删除执行变量。我已经试过普通交易-没有结果。现在我想到了补偿事件。 问题: 补偿事件是回滚Activiti上下文还是应该在适当的CompensationserviceTask中手动执行?