【问题标题】:Axon - SubscribingEvent vs TrackingEvent processorAxon - SubscribingEvent 与 TrackingEvent 处理器
【发布时间】:2019-03-06 10:08:57
【问题描述】:

我目前在 Axon 中使用 SubscribingEvent 处理器。使用它,所有内容都在单线程中执行(因为我想在单线程中执行命令并将事件应用于投影)确保所有内容都保存到数据库或回滚。

如果我们使用 TrackingEvent 处理器,如果该命令在 Aggregate 中成功执行并且 Aggregate 发出的事件被保存到 DB,但应用程序在 Projections 完成之前失败(这意味着没有保存到 DB),会发生什么?重新启动后的应用程序会继续投射此事件吗?

在我的情况下,我正在对 REST 调用进行投影,所以我想使用 SubscribingEvent 处理器对我来说是有意义的(所以要么一切正常,要么什么都没有)。如果我使用 TrackingEvent 处理器,并且应用程序在保存和投影之间崩溃 - 我会有不一致的状态。即使投影在下次启动时重新启动(我假设是这样),客户端也会再次发送相同的命令(认为它失败了),但是如果它第二次收到相同的命令会发生什么?

【问题讨论】:

    标签: java domain-driven-design cqrs event-sourcing axon


    【解决方案1】:

    让我尝试为您提供一些见解!

    如果我们使用 TrackingEvent 处理器,如果该命令在 Aggregate 中成功执行并且 Aggregate 发出的事件被保存到 DB,但应用程序在 Projections 完成之前失败(这意味着没有保存到 DB),会发生什么?

    Axon 中的TrackingEventProcessor 通过TrackingToken 跟踪它处理过的事件。跟踪处理器只会在调用所有事件处理组件(例如更新您的投影的组件)之后更新TrackingToken。 因此,在该时间点重新启动时,跟踪处理器将再次处理该事件。在这样做时,它会尝试与您的整个事件流保持同步。

    如果我使用 TrackingEvent 处理器,并且应用程序在保存和投影之间崩溃 - 我的状态会不一致。

    这取决于您实现应用程序的方式。听起来一切都非常紧密耦合,这样做并没有接受你必须处理最终一致性的事实。我知道说起来容易做起来难,但是让您的前端在您发出命令时期望立即响应最终会简化系统。话又说回来,这在很大程度上取决于您是否可以影响 UI 对做事的看法;不确定这是否适合您的情况。

    即使在下次启动时重新启动投影(我假设是这样),客户端也会再次发送相同的命令(认为它失败了),但是如果它第二次收到相同的命令会发生什么?

    这完全取决于您实施聚合的方式。聚合应决定是否可以执行命令。如果该决策的一部分是确保先前的命令与当前操作不同,那么您需要在 @CommandHandler 带注释的函数中考虑到这一点。

    我希望这能给 Bojan 一些见解,并毫不犹豫地回答更多问题以掌握 Axon 的这一部分。

    【讨论】:

    • 谢谢。现在更清楚了。只需再澄清一项与TrackingEventProcessor 相关的说明。你说TrackingToken 的更新将在所有事件处理程序被调用之后发生。这意味着如果我有 2 个投影组件,并且组件 1 已成功将投影保存到 db,并且就在第二个组件将投影保存到 db 之前 - 组件被杀死。重新启动时,第一个投影组件和第二个将再次收到相同的事件?这意味着 - 我还需要在投影中处理重复数据删除(在本例中为组件 1,因为组件 2 尚未处理它)?
    • 啊,抱歉在这方面有点含糊,让我详细说明一下。 Axon 将在同一事务中发出TrackingEventProcessor 下的所有事件处理程序(通过利用UnitOfWork,可以启动和停止事务)。因此,如果您的第一个事件处理程序成功更新投影而第二个事件处理程序失败,则整个事务将回滚。因此,您不必在该空间中处理重复数据删除。
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多