为了使域事件处理保持一致,我想在保存AggregateRoot
. 稍后使用事件处理器对它们做出反应,例如假设我想将它们作为集成事件发送到事件总线,我想知道在通过总线后是否允许从数据库中删除事件?因此,事件将永远不会被AggregateRoot
根加载。
2 回答
领域事件是过去发生的事情。你不能删除过去,假设你不是 Martin McFly :)
不应从事件存储中删除域事件。如果你想知道你之前是否已经处理过它,你可以添加一个标志来知道它。
更新 ==> 事件管理流程描述
我以这种方式遵循 IDDD(Vaughn Vernon 的红皮书,参见第 287 页的图片)的方法:
1)聚合将事件本地发布到BC(轻量级发布者)。
2)在BC中,轻量级订阅者将BC发布的所有事件存储在“事件存储”(即BC同一个数据库中的表)中。
3)批处理(工作人员)读取事件存储并将事件发布到消息队列(或您所说的事件总线)。
4)其他对事件感兴趣的BC(甚至是同一个BC)订阅消息队列(或事件总线)来监听和响应事件。
无论如何,即使工作人员已经将事件发送到消息队列中,您也不应该从事件存储中删除域事件。相反,只是不要再次发送它,但事件是已经发生的事情,您不能(不应该)删除过去发生的事情。
消息队列或事件总线只是一种发送/接收事件的机制,但事件应保持存储在它们创建和发布的 BC 中。
我想知道是否允许反应器在反应后从数据库中删除事件。
您可能需要查看Udi Dahan 的Reliable Messaging without Distributed Transactions;还有 Pat Helland 的论文Life Beyond Distributed Transactions。
在事件源系统中,这意味着域事件的历史是聚合的持久历史,您几乎永远不会删除事件。
在一个系统中,域事件日志只是要与其他“伙伴”通信的消息日志:从根本上说,域事件是描述要从系统的一个部分复制到另一个部分的信息的消息。因此,当我们得到消息已成功复制的确认时,我们可以删除存储在“此处”的副本。
在您不能确定所有消费者都收到了域事件的系统中(因为,也许消费者列表不明确),那么您可能无法删除域事件。
您也许可以移动它们——也就是说,您可以从事件历史中显式订阅聚合,然后隐式订阅历史,而不是隐式订阅聚合。
您也许可以将域事件的记录视为缓存——如果合作伙伴在消息可用后 7 天内没有完成使用消息,那么消息的传递可能不是系统中最大的问题.
您需要多少个九的交货保证?