2

我正在开发一个 CQRS+ES 系统,主要使用 axon 框架,但实际上这个问题适用于任何实现。所以我有一个命令处理程序和 1 个或多个事件处理程序,在不同的 JVM、容器等上运行,并且在某些时候这些处理程序之一遇到错误。

我们有两种情况,一个“预期的”业务错误和一个“意外的”系统错误。据我了解,我们现在处于异步处理程序中,事件现在已成为事实,因此实际上我们不能直接回滚两种情况下的命令(因为它可能需要在许多其他投影中回滚并破坏 CQRS)。

所以我的问题是,这样的错误是否应该以账户分类账的方式“解决”,即通过发送一个新的“逆转”命令,然后以这样的方式传播到预测,以便现在解决失败的事件?

例如,假设我们有一个更新客户信用的命令。该事件被发布,一个投影更新其“总信用”统计数据,另一个将更新发布到 UI 的某些 websocket,最后,另一个维持信用状态 - 最后一个处理程序失败。我们是否应该发送回滚业务事务的命令,再次扣除信用,再次更新 websocket 等?如果是轴突,是否有某种方式可以将其捕获为交易?

4

1 回答 1

1

我想说的是,决定是否采取行动,从而处理命令,是否可以,应该始终取决于命令模型/聚合。聚合处于不正确状态以处理操作通常会导致“业务异常/错误”。

但是,如果您要在事件处理失败时做出决策,那么您将在事件处理服务中添加一些决策逻辑,在大多数情况下它可能并不关心。这样的事件处理服务会更新视图/查询模型,但未能这样做,我认为这不是将“补偿命令”发布到您的聚合以“回滚/撤消事件”的正当理由。

在您的示例中,您有一个“信用状态维护者”,我猜它会更新查询模型。因此,我认为处理异常的问题在于服务本身,而不是通过执行补偿操作。

从 Axon 框架的角度来看,您可以将您的 a 包装CreditStateEventHandler在 a 中,并通过调用该函数TrackingEventProcessor触发该事件处理器上的重置。TrackingEventProcessor#resetTokens()这是一种立场,即您的异常CreditStateEventHandler当然是由于编码错误造成的,否则重播将导致完全相同的异常。

于 2018-05-30T08:13:02.010 回答