DomainEventPublisher的一致性

时间:2018-11-21 09:51:25

标签: domain-driven-design aggregateroot

刚刚阅读了沃恩·弗农(Vaughn Vernon)的effective aggregate design,我想知道与事件发布相关的失败。

在第9页(PDF的第3页)的给定示例中,我们称为DomainEventPublisher.publish()。正在发布的事件允许其他聚合执行其行为。

我想知道的是:如果DomainEventPublisher.publish()失败了怎么办?如果DomainEventPublisher.publish()成功但事务失败了怎么办?

实现如何处理这两种情况?

2 个答案:

答案 0 :(得分:2)

DomainEventPublisher.publish()是同步的。您将设置一个generic handler (handles all events),将事件存储在与业务流程相同的数据库事务中,这意味着您的事件存储必须具有与您依赖的任何其他存储机制进行事务处理的能力继续存储聚合状态。

一旦将事件写到磁盘上,就可以将它们放在消息队列中以进行异步传递。

  

还有其他已知的方法吗?

好吧,与其使用静态的DomainEventPublisher,您可以将事件记录在AR上的集合中,就像在事件源中一样,然后实现集中化的机制来存储它们(例如,事务挂钩,使用方面等)。 )。

答案 1 :(得分:0)

  

如果DomainEventPublisher.publish()成功,会发生什么,但是   交易失败?

在这种情况下,我反对弗农的做法。我更喜欢return the events到应用程序服务。这样,我可以使用事务(如果需要)保留聚合执行的更改,并且如果一切正常,我将发布该事件。这也有助于保持业务层完全干净和纯净。

用几句话;如果交易失败,则不会引发任何事件。

  

如果DomainEventPublisher.publish()失败会怎样?

根据业务规则,域事件绝不会失败,因为它是对已发生事件的通知。如果汇总对操作说“是”,并返回一个表示业务变化的事件;那么世界上没有什么可以说此操作无法完成或必须撤消。

如果事件因基础架构而失败,那么您需要使用工具在故障修复后自动(或手动)重新引发该事件,并最终将其一致性归档在系统中。看一下NServiceBus。它提供重试,错误队列,日志等,以永不丢失事件。 如果消息系统出现故障,则至少会有事件日志,您可以使用这些事件日志将它们重新上升到消息系统中。