我正在使用CQRS + ES系统,主要使用轴突框架,但实际上这个问题适用于任何实现。所以我有一个命令处理程序和一个或多个事件处理程序,在不同的JVM,容器等上运行,并且在某些时候这些处理程序中的一个遇到错误。
我们有两个案例,一个'预期'商业错误和意想不到的'系统错误。据我所知,我们现在处于异步处理程序中,事件现在已成为事实,所以实际上我们无法直接回滚命令(因为它可能需要在许多其他预测中将其回滚并打破CQRS)。
所以我的问题是,如果这样的错误被解决了吗?在帐户分类帐中,即通过发送新的'逆转'然后将命令传播到投影,以便现在解决失败的事件?
举个例子,我们假设我们有一个更新客户信用的命令。该活动已经发布,其中一个预测更新了其总排名"统计数据,另一个发布更新到UI的一些websocket,最后,另一个维护信用状态 - 并且最后一个处理程序失败。我们是否应该发送回滚业务交易的命令,再次扣除信用额度,再次更新websocket等等?在轴突的情况下,有哪些方法可以将其作为交易捕获?
答案 0 :(得分:1)
我声明决定是否采取行动,因此处理命令是可以的,应始终使用Command Model / Aggregate。处理操作的聚合处于错误状态通常会导致“业务异常/错误”。
如果您在事件处理失败时做出决定,那么您在事件处理服务中添加了一些决策逻辑,在大多数情况下它可能并不关心。这样的事件处理服务更新视图/查询模型,但没有这样做,我认为这不是向聚合发布“补偿命令”以“回滚/撤消事件”的正当理由。
在你的例子中,你有一个'信用状态维护者',我猜它会更新一个查询模型。因此,我认为处理异常的问题在于服务本身,而不是通过执行补偿操作。
从Axon Framework的角度来看,您可以将CreditStateEventHandler
包裹在TrackingEventProcessor
中,并通过调用TrackingEventProcessor#resetTokens()
函数触发该事件处理器的重置。这是因为CreditStateEventHandler
因编码错误而导致的异常,否则重放将导致完全相同的异常。