Events 使用回滚进行事件聚合器错误处理

Events 使用回滚进行事件聚合器错误处理,events,exception-handling,event-handling,domain-driven-design,eventaggregator,Events,Exception Handling,Event Handling,Domain Driven Design,Eventaggregator,我一直在研究开发人员在领域驱动设计上设计/构建应用程序的许多常用方法,但仍然试图从整体上理解这个概念。我看到的一些示例包括通过事件聚合器使用事件。我喜欢这个概念,因为它确实使应用程序的不同元素/域保持解耦 我关心的一个问题是:如果发生错误,如何回滚操作 例如: 假设我有一个订单应用程序,它必须将订单保存到数据库,并将订单副本作为pdf保存到CMS。应用程序触发一个事件,表示已创建新订单,订阅此事件的pdf服务将保存pdf。同时,将订单更改提交到数据库时,会引发异常。问题是pdf已经保存,但它们不

我一直在研究开发人员在领域驱动设计上设计/构建应用程序的许多常用方法,但仍然试图从整体上理解这个概念。我看到的一些示例包括通过事件聚合器使用事件。我喜欢这个概念,因为它确实使应用程序的不同元素/域保持解耦

我关心的一个问题是:如果发生错误,如何回滚操作

例如:

假设我有一个订单应用程序,它必须将订单保存到数据库,并将订单副本作为pdf保存到CMS。应用程序触发一个事件,表示已创建新订单,订阅此事件的pdf服务将保存pdf。同时,将订单更改提交到数据库时,会引发异常。问题是pdf已经保存,但它们不是匹配的数据库记录

我是否应该缓存以前处理过的事件并触发一个新的错误事件,以查找缓存中的撤消操作?为此使用类似于命令模式的东西

或者。。。事件聚合器不是一个很好的模式

编辑

我开始认为,事件可能应该用于任务不那么关键的项目,如电子邮件和日志记录


我最初的想法是通过使用事件聚合器模式来限制依赖关系。

只有当事件处理程序参与事务时,在事件实际发生之前处理事件才有效。例如,通过将PDF存储在数据库中,或在事务提交后发布和处理事件,使事件处理程序具有事务性。

只有当事件处理程序参与事务时,在事件实际发生之前处理事件才有效。例如,通过将PDF存储在数据库中,或在事务提交后发布和处理事件,使事件处理程序具有事务性。

您希望在与数据库上的操作相同的事务中提交事件

在这个特定的场景中,您可以将事件推送到队列上,队列登记在您的事务中,这样,除非聚合被持久化,否则事件将永远不会出去。这将使创建PDF最终保持一致;如果创建PDF失败,您可以修复该问题,并自动重试


也许你可以从我之前在上的一篇文章中获得更多灵感。

你希望事件在与数据库操作相同的事务中提交

在这个特定的场景中,您可以将事件推送到队列上,队列登记在您的事务中,这样,除非聚合被持久化,否则事件将永远不会出去。这将使创建PDF最终保持一致;如果创建PDF失败,您可以修复该问题,并自动重试


也许你可以从我之前在上的一篇文章中获得更多灵感。

我明白了将PDF存储在数据库中的要点,但如果PDF创建失败,记录创建后的第二个触发事件会导致相同的问题。@Chris 2pc commit如果你需要以原子方式存储数据库和cms,但我很怀疑这是否必要。@Chris这不是同一个问题。创建PDF时失败是一个错误,但为不存在的订单创建PDF会导致不一致。事件处理程序可能会失败-修复该问题并再次处理该事件。我看到了将PDF存储在数据库中的要点,但如果PDF创建失败,则记录创建后触发事件的第二点会导致相同的问题。@Chris 2pc commit如果需要以原子方式存储数据库和cms,但我很怀疑这是否必要。@Chris这不是同一个问题。创建PDF时失败是一个错误,但为不存在的订单创建PDF会导致不一致。事件处理程序可以失败-修复问题并再次处理事件;查找Udi Dahan域事件拯救。记住你也可以使用内存中的事件;查找Udi Dahan域事件。