具有副作用的事件采购

时间:2016-01-04 23:28:44

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

我正在使用熟悉的事件采购模式构建服务:

  1. 收到请求。
  2. 加载了汇总的历史记录。
  3. 聚合重建(来自其历史)。
  4. 准备新事件并更新聚合以响应来自步骤1的传入请求。
  5. 这些事件将写入日志,并可供任何订阅者使用(发布)。
  6. 就我而言,第5步分两部分完成。事件将写入事件日志。后台进程从事件日志中读取并发布从偏移量开始的所有事件。

    在某些情况下,除了与聚合相关的事件之外,我还需要发布副作用。就系统而言,这些也是事件,因为它们被其他服务消耗并影响其他服务的状态。但是,它们不会影响此服务中聚合的历史记录,也不需要重建它。

    我应该如何在代码中处理这些?

    选项1- 不要将副作用事件写入事件日志。在步骤5之前的主要流程中发布这些内容。

    选项2- 将所有内容写入事件日志,并在加载历史记录时忽略副作用事件。 (这些不是历史的一部分!)

    选项3- 将副作用事件写入虚拟聚合,以便它们被发布,但从未加载。

    选项4- ?

    在第一个选项中,如果存在并发冲突,则可能会出现问题。如果在步骤5中写入失败,则副作用不能轻易回滚。第二个选项写入不属于聚合历史记录的事件。在步骤2中加载时,必须忽略这些副作用事件。第三种选择感觉像是黑客。

    这些对你来说哪个适合你?

3 个答案:

答案 0 :(得分:5)

正确命名事件

事件是“发生的事情”。 因此,如果您能够命名仅以“X发生”方式触发副作用的事件,它们将成为事件历史记录的自然组成部分。

根据我的经验,这总是可行的,因为副作用不是凭空发生的。有时名称变得有点人为,但命名事件比调用它们更好,例如“向该客户活动发送电子邮件”。

就您的备选方案列表而言,这将是选项2。

实施例

不是将事件“发送状态电子邮件发送给客户事件”,而是将其称为“状态电子邮件触发事件”。当然,如果实际触发器有更好的名称,请使用该名称: - )

答案 1 :(得分:1)

选项4 - 让一些其他服务订阅事件并产生副作用,以及与它们相关的任何其他事件。

事件应该是细粒度的。

答案 2 :(得分:0)

  

选项1-不要将副作用事件写入事件日志。发布   这些在步骤5之前的主要过程中。

如果您以后需要通过构建新的有界上下文来获取历史记录,那该怎么办?

  

选项2-将所有内容写入事件日志并忽略副作用   加载历史记录时的事件。 (这些不是历史的一部分!)

如何忽略没有任何效果的东西的效果? :d

  

选项3-将副作用事件写入虚拟聚合,使它们成为   已发布,但从未加载。

为什么你需要一些你永远不会改变的东西的一致性边界?

您所谈论的是最常见的域事件形式,您可以使用它来与其他BC-s进行通信。 OFC。你需要保存它们。