领域事件可以删除吗?

Can domain events be deleted?

为了使域事件处理保持一致,我想在保存 AggregateRoot 的同时将域事件持久化到数据库中。稍后使用事件处理器对它们做出反应,例如,假设我想将它们作为集成事件发送到事件总线,我想知道是否允许在通过总线传递事件后将其从数据库中删除? 所以事件永远不会再用 AggregateRoot 根加载。

I wonder whether or not the reactor is allowed to remove the event from db after the reaction.

您可能想要查看 Reliable Messaging Without Distributed Transactions, by Udi Dahan; also Pat Helland's paper Life Beyond Distributed Transactions

在事件源系统中,这意味着域事件的历史聚合的持久历史,您几乎永远不会删除事件。

在一个系统中,领域事件的日志只是要与其他人交流的消息日志"partners":从根本上说,领域事件是描述要从系统的一部分复制的信息的消息给另一个。因此,当我们收到消息已成功复制的确认信息时,我们可以删除存储的副本 "here".

在您无法确定所有消费者都收到领域事件的系统中(因为消费者列表可能不明确),您可能无法删除领域事件。

您可以移动它们——也就是说,您可以从事件历史到聚合的显式订阅,然后是对历史的隐式订阅,而不是对聚合进行隐式订阅。

可能能够将领域事件的记录视为缓存——如果合作伙伴在消息可用后的 7 天内未使用完消息,那么也许消息的传递不是系统中最大的问题。

您需要多少个九的交货保证?

领域事件是过去发生的事情。你不能删除过去,假设你不是 Martin McFly :)

不应从事件存储中删除域事件。如果想知道之前有没有处理过,可以加个flag知道。

更新 ==> 事件管理过程的描述

我按照 IDDD(Vaughn Vernon 的红皮书,见第 287 页图片)的方法是这样的:

1) 聚合将事件本地发布到 BC(轻量级发布者)。

2) 在BC中,一个轻量级订阅者将BC发布的所有事件存储在一个"event store"中(与BC同一个数据库中的一个table)

3) 批处理(worker)读取事件存储并将事件发布到消息队列(或您所说的事件总线)。

4)其他对该事件感兴趣的BC(甚至同一个BC)订阅消息队列(或事件总线)监听事件并做出反应

无论如何,即使工作人员已将事件发送到消息队列,您也不应从事件存储中删除域事件。而是简单地不再发送它,但事件是已经发生的事情,你不能(不应该)删除过去发生的事情。

消息队列或事件总线只是 send/receive 事件的一种机制,但事件应保留在创建和发布它们的 BC 中。