【问题标题】:CQRS aggregatesCQRS 聚合
【发布时间】:2015-10-06 07:58:12
【问题描述】:

我是 CQRS/ES 领域的新手,我有一个问题。我正在开发一个使用事件溯源和 CQRS 的发票 Web 应用程序。

我的问题是——据我了解,进入系统的新命令(比如说 ChangeLineItemPrice)应该通过域模型,以便可以将其验证为合法命令(例如,检查该行项目是否真的存在,价格不违反任何业务规则等)。如果一切顺利(命令未被拒绝)- 则创建并存储相应的事件(例如 LineItemPriceChanged)

我不太明白的是,在尝试应用命令之前,我如何将这个聚合保存在内存中。如果系统中有一百万张发票,是否应该在每次应用命令时回放整个历史记录?我是否总是在不进行任何验证的情况下保存事件并在构建视图模型/投影时进行验证?

如果我误解了流程的任何部分,我会感谢您的反馈。

感谢您的帮助!

【问题讨论】:

    标签: domain-driven-design cqrs event-sourcing system-design


    【解决方案1】:

    您必须重播事件以“补充”域聚合是正确的。但是您不必重播所有发票的所有事件。如果将根聚合的实体 id 存储在事件中,则只需选择并重播具有相关 id 的事件。

    那么,如何找到相关的聚合根 id?其中一个读取存储库应包含根据一组搜索条件获取 id 的相关信息。

    【讨论】:

      【解决方案2】:

      你并不孤单,这是一个常见的误解。让我先回答验证部分:

      在这种系统中进行了 2 种类型的验证。第一种是您查找有效电子邮件地址、仅数字或必填字段的类型。这种类型甚至在命令发出之前就完成了。不应将包含此类问题的命令作为命令提出(对于皮带和大括号,您可以在域端进行检查,但这不是域问题,最好只是防止这种情况)。

      下一种类型的验证是当它一个域问题时。它可能是你提到的那种你检查价格是否在一组指定参数内的事情。这是业务人员能够理解、执行并能够表达的领域概念。

      下一阶段是域应用状态更改并引发相关事件。然后将这些内容持久化,并在成功后发布到应用程序的其余部分。

      所有这些都可以通过内存中的聚合来完成。这些动作与处理命令的域服务协调。它加载聚合,应用所有 it's 过去的事件(或加载快照),然后发出命令。命令成功后,它会请求所有新的未提交事件并尝试持久化它们。成功后,它会发布新事件。

      如您所见,它仅加载该特定聚合的事件。即使有很多事件,这个过程也很快。如果性能是一个问题,您可以应用一些策略,例如将聚合保存在内存中或快照。

      关于验证事件的最后一点。由于它们只能由您的聚合生成,因此它们是值得信赖的。

      如果您想了解更多详细信息,请查看我对 CQRS 和 ES 的概述here。并查看我关于如何构建聚合根here 的帖子。

      祝你好运 - 我希望他们有所帮助!

      【讨论】:

      • 谢谢,这很有帮助!
      猜你喜欢
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      相关资源
      最近更新 更多