【问题标题】:How to handle failed Aggregate in Domain Driven Design如何在领域驱动设计中处理失败的聚合
【发布时间】:2018-03-04 10:53:01
【问题描述】:

我在 Web 应用程序上有一个复杂的注册表单。当用户提交该注册表单时,一个命令是 分派给命令处理程序。这将创建一个聚合。然后它将被持久化到非规范化的数据库中,并 也是一个活动商店。当此事务完成时,将发布一个事件。由于那个事件,另一个聚合最终将是 由事件处理程序创建。

只有在创建了两个聚合时,注册才真正完成。这应该发生在同一个过程中,但两者 有自己的交易。 (最终一致)

所以理论上AggregateOne 可能会同时保存到非规范化数据库和事件存储中,但是 AggregateTwo 可能由于错误或验证错误(例如:需要用户名)而在进程中的某处抛出异常。

这意味着我的注册不完整,因为只有一半的数据得到了持久化。但用户希望看到 他输入的所有数据。

在领域驱动设计中如何解决此类问题?


注意:我真的没有复杂的注册表单。这只是一个示例场景。我只是对如何解决这些问题感兴趣。

【问题讨论】:

    标签: domain-driven-design aggregateroot


    【解决方案1】:

    我猜你在这里描述的注册实际上是一个过程。所以它有几个步骤需要一些时间才能完成,并且不仅要处理快乐的道路,还要处理一些极端情况。

    正如您所描述的,创建第二个聚合可能会导致错误,从而偏离正确的路径。

    因为您谈论的是命令和事件,我假设您已经将域驱动设计的想法与 CQRS 概念结合起来。

    为此,您需要一个流程管理器。如果您想了解领域驱动设计和 CQRS 上下文中的流程管理器,您可以搜索术语 Saga 或流程管理器。

    流程管理器是一个简单的组件,它注册聚合发出的事件并发送命令作为响应。流程管理器有一个内部状态来跟踪进度并根据状态和事件决定接下来要发送哪个命令。

    请记住,流程管理器实例的生命周期与聚合不同,尽管它们看起来非常相似。流程实例在收到不同事件时开始,并在一段时间后以事件结束。

    为了使您的进步发挥作用,您还应该将错误建模为事件。因此,您的第二个聚合可以向创建命令发出 SuccesslyCreate 或 CreationDenied 事件。从技术上讲,CreationDenied 事件可能是一个例外,但它更容易发出业务驱动的事件。

    然后您的流程简单地发送命令以创建您的第二个聚合,将该事实存储在其状态中,并在接收到任何一个或可能的结果事件时采取相应的行动。

    流程经理对偏离幸福路径的事件的反应通常称为补偿。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-01
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      相关资源
      最近更新 更多