Axon Framework - 我如何回滚 Saga 进程
Axon Framework - How can i rollback a Saga process
我使用的是 Axon Framework,没有带 spring-boot 自动配置的 Axon 服务器。我的问题是:如果我正在 运行ning 一个 saga 进程,如下所示,并且在处理过程中 运行 磁盘不足,将会出现异常,我必须回滚。我怎样才能做到这一点?我需要回滚多少?
我的saga_entrytable会是这样的:
SAGA_ID: 22ad255b-4378-4bb4-84c2-061ca666c6e7, REVISION: null, SAGA_TYPE: hu.saga.account.SagaAccount, SERIALIZED_SAGA: 3c68752e6d6f6c617269732e736167612e6163636f756e742e536167614163636f756e742f3e
我的association_value_entrytable会是这样的:
ID:2,ASSOCIATION_KEY:账户 ID,ASSOCIATION_VALUE:11,SAGA_ID:22ad255b-4378-4bb4-84c2-061ca666c6e7,SAGA_TYPE:hu.saga.account.SagaAccount
并且在我的 domain_event_entry table 中只有两个事件(不是应该的 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()));
}
我写 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");
}
我的意思是,如果我不处理它,传奇 tables 将不会像它应该的那样是空的,而且我不能为该聚合 ID:11 触发另一个传奇,因为它已经存在于 domain_event-entry table
如何从 domain_event_entry table 中删除? AggregateLifecycle.markdeleted() 对我不起作用。
我想从注意到 Saga 为复杂业务事务的单个实例建模开始。
Axon 提供了很多关于该主题的文档,您可以阅读 here.
然后转到您的 Saga 代码段,您似乎在帐户聚合的开头启动了一个 Saga 代码段。
我认为从 Account/Wallet 的角度来看,这根本不是 Saga 的正确起点,我假设你在其中。
相反,您的 Saga 应该模拟一个 单一 (复杂业务)交易,因此只是取款或存款。
AxonIQ 和 Pivotal 去年合作提供了这样一个使用 Saga 的示例项目,Axon Trader。
我建议您查看此项目,以进一步了解如何处理一般的 Saga。
顺便回答一下标题问题:您永远不会亲自回滚 Saga。如果存在异常状态,Axon 的 Unit of Work 概念将 kick-in 回滚 阶段以恢复某些操作。
如果某些东西应该回滚 在异常状态的概念之外,那么你应该自己处理。
这是必要的,因为您的 Saga 对整个交易进行建模,因此也是错误状态。
您通常会调度补偿操作(例如命令)作为对故障状态的反应。
希望这能为您澄清一些事情。
我使用的是 Axon Framework,没有带 spring-boot 自动配置的 Axon 服务器。我的问题是:如果我正在 运行ning 一个 saga 进程,如下所示,并且在处理过程中 运行 磁盘不足,将会出现异常,我必须回滚。我怎样才能做到这一点?我需要回滚多少?
我的saga_entrytable会是这样的:
SAGA_ID: 22ad255b-4378-4bb4-84c2-061ca666c6e7, REVISION: null, SAGA_TYPE: hu.saga.account.SagaAccount, SERIALIZED_SAGA: 3c68752e6d6f6c617269732e736167612e6163636f756e742e536167614163636f756e742f3e
我的association_value_entrytable会是这样的:
ID:2,ASSOCIATION_KEY:账户 ID,ASSOCIATION_VALUE:11,SAGA_ID:22ad255b-4378-4bb4-84c2-061ca666c6e7,SAGA_TYPE:hu.saga.account.SagaAccount
并且在我的 domain_event_entry table 中只有两个事件(不是应该的 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()));
}
我写 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");
}
我的意思是,如果我不处理它,传奇 tables 将不会像它应该的那样是空的,而且我不能为该聚合 ID:11 触发另一个传奇,因为它已经存在于 domain_event-entry table
如何从 domain_event_entry table 中删除? AggregateLifecycle.markdeleted() 对我不起作用。
我想从注意到 Saga 为复杂业务事务的单个实例建模开始。 Axon 提供了很多关于该主题的文档,您可以阅读 here.
然后转到您的 Saga 代码段,您似乎在帐户聚合的开头启动了一个 Saga 代码段。 我认为从 Account/Wallet 的角度来看,这根本不是 Saga 的正确起点,我假设你在其中。 相反,您的 Saga 应该模拟一个 单一 (复杂业务)交易,因此只是取款或存款。
AxonIQ 和 Pivotal 去年合作提供了这样一个使用 Saga 的示例项目,Axon Trader。 我建议您查看此项目,以进一步了解如何处理一般的 Saga。
顺便回答一下标题问题:您永远不会亲自回滚 Saga。如果存在异常状态,Axon 的 Unit of Work 概念将 kick-in 回滚 阶段以恢复某些操作。
如果某些东西应该回滚 在异常状态的概念之外,那么你应该自己处理。 这是必要的,因为您的 Saga 对整个交易进行建模,因此也是错误状态。 您通常会调度补偿操作(例如命令)作为对故障状态的反应。
希望这能为您澄清一些事情。