Axon 框架 - 我如何回滚 Saga 进程

pol*_*oft 3 java saga axon spring-boot

我正在使用 Axon 框架,而没有带有 spring-boot 自动配置的 Axon 服务器。我的问题是:如果我正在运行一个 saga 进程,如下所示,并且在处理过程中我的磁盘用完了,将会出现异常,我必须回滚。我怎样才能做到这一点?我必须回滚多少?

我的 saga_entry 表将是这样的:

SAGA_ID:22ad255b-4378-4bb4-84c2-061ca666c6e7修订:空,SAGA_TYPE:hu.saga.account.SagaAccount,SERIALIZED_SAGA:3c68752e6d6f6c617269732e736167612e6163636f756e742e536167614163636f756e742f3e

我的 association_value_entry 表将是这样的:

ID: 2, ASSOCIATION_KEY: accountId, ASSOCIATION_VALUE: 11, SAGA_ID: 22ad255b-4378-4bb4-84c2-061ca666c6e7, SAGA_TYPE: hu.saga.account.SagaAccount

在我的 domain_event_entry 表中将只有两个事件(而不是应该是 3 个) AccountCreatedEvent, MoneyWithdrawnEvent ,聚合 id: 11 。

这只是一个例子,主要问题可能是在 Axon Saga 中处理和实现回滚的最佳方法是什么?

@StartSaga
@SagaEventHandler(associationProperty = "accountId")
public void handle(AccountCreatedEvent event){
    logger.info("Saga Start");
    commandGateway.send(new WithdrawMoneyCommand(event.getAccountId(), event.getAccountId(),event.getOverDraftLimit()));
}
Run Code Online (Sandbox Code Playgroud)

我写 null 来模拟在 DepositMoneyCommand 构造函数中的潜在回滚

@SagaEventHandler(associationProperty = "accountId")
public void handle(MoneyWithdrawnEvent event){
    commandGateway.send(new DepositMoneyCommand(null,event.getTransactionId(),event.getAmount()));
}


@EndSaga
@SagaEventHandler(associationProperty = "accountId")
public void handle(MoneyDepositedEvent event){
    logger.info("Saga End");
}
Run Code Online (Sandbox Code Playgroud)

我的意思是如果我不处理它,saga 表不会像它应该的那样为空,并且我不能为该聚合 id: 11 触发另一个 saga,因为它已经存在于 domain_event-entry 表中

如何从 domain_event_entry 表中删除?AggregateLifecycle.markdeleted() 对我不起作用。

Ste*_*ven 5

我喜欢首先注意到 Saga 对复杂业务事务的单个实例进行建模。Axon 提供了很多关于该主题的文档,您可以在此处阅读。

然后转到您的 Saga 代码段,您似乎正在帐户聚合的开头启动 Saga 代码段。我认为从我假设您所处的账户/钱包的角度来看,这根本不是 Saga 的正确启动点。相反,您的 Saga 应该模拟单个(复杂的业务)交易,因此只是取款或存款。

AxonIQ 和 Pivotal 去年合作,为此使用 Saga 提供了这样一个示例项目,即Axon Trader。我建议您查看这个项目,以进一步了解如何处理 Saga。

顺便说一下,回答标题问题:您永远不会亲自回滚 Saga。如果出现异常状态,Axon 的工作单元概念将启动回滚阶段以恢复某些操作。

如果某些事情应该在异常状态的概念之外回滚,那么您应该自己处理。这是必要的,因为您的 Saga 对整个交易进行建模,因此也对错误状态进行建模。您通常会调度补偿动作(例如命令)作为对错误状态的反应。

希望这可以为您澄清一些事情。