域事件应该在事务内部还是外部引发?

发布于 2024-10-12 04:53:18 字数 413 浏览 3 评论 0原文

在我们的应用程序中,当域模型中发生某些变化时,我们会引发域事件。事件处理程序执行的某些任务必须在引发事件时使用的同一事务内完成,其他任务必须在此事务之外执行。

例如,

当将 Orderline 添加到 Order 实体时,会引发 OrderLineAdded 域事件,一个域事件会更改域模型的状态(因此必须在同一事务中执行),然后当事务完成时,UI 必须被更新。

您将如何解决这个问题?

  1. 引发两个事件,一个在事务内部,一个在事务外部。
  2. 在事务内部引发事件,但使用事件处理程序发送异步请求来更新 UI?

选项 1 似乎令人困惑,因为事件名称必须以某种方式传达它们位于事务内或事务外,但使用选项 2 时,域事件处理程序必须始终假设它们是从事务内同步调用的。

也许有更好的方法?

In our application we raise domain events when something changes in the domain model. Some of the tasks that are performed by the event handlers must be done within the same transaction that was used when the event is raised, other tasks must be performed outside of this transaction.

For example,

When an Orderline is added to an Order entity, the OrderLineAdded domain event is raised, one domain event changes the state of the domain model (so must be performed in the same transaction), then when the transaction is completed the UI must be updated.

How would you approach this problem?

  1. Raise two events, one inside the transaction, and one outside of the transaction.
  2. Raise the event inside of the transaction, but use the event handler to send an Async request to update the UI?

Option 1 seems confusing, since the events names must somehow convey they are in or out of a transaction, but with option 2 handlers of the domain event must always assume that they are called synchronously from within a transaction.

Maybe there is a better approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑾夏年华 2024-10-19 04:53:18

我也遇到过类似的问题。域模型正在发布事件(使用 Udi Dahan 在此处描述的技术)。然后我意识到,即使出现问题并且事务稍后回滚,我的 UI 相关处理程序也会被调用。

为了解决这个问题,我向系统引入了另一个角色,即另一种事件处理程序。我有 ITransactionalEventHadnelerINonTransactionalEventHandler。前者在 DomainEvents.Publish() 方法中立即同步调用。后者会在事务提交后立即排队等待调用(使用 System.Transactions 挂钩)。该解决方案运行良好,并且具有良好的可读性和可维护性。

I've had a similar problem. Domain model was publishing events (using the technique Udi Dahan describes here). Then I realized that my UI-related handlers are invoked even if something goes wrong and transaction is rolled back later.

To fix this I introduced another role to the system, another kind of event handler. I has ITransactionalEventHadneler and INonTransactionalEventHandler. The former were invoked synchonously immediately in DomainEvents.Publish() method. The latter were queued to be invoked as soon as transaction gets committed (using System.Transactions hooks). The solution worked fine and was quite readable and maintainable.

凌乱心跳 2024-10-19 04:53:18

我认为这两种方法都很好,只需在代码的每个部分坚持相同的方法:

  1. 您将需要两个(或更多)事件处理程序,一个用于事务范围内的域模型的上下文,另一个用于) 用于辅助上下文,例如 UI。您的域代码不应该关心代码的其他部分做什么,只需通知它们域数据的更改即可。
  2. 您的域代码事件处理程序方法可能会将异步事件发送到 UI 或其他模块。域事件应该是同步的,否则您需要两阶段提交来保持事务性。

我个人更喜欢选项2,因为它使域代码保持干净,并且通过使用异步通信,核心和其他模块将解耦,因此外部模块的问题不会妨碍核心的工作。另一方面,在某些情况下,选项 1 可能更有利。

I think both approach could be good, just stick to the same approach in every part of your code:

  1. you'll need two (or more) event handlers, one for the context of the domain model that's inside the transaction scope and other(s) for the auxiliary contexts, like the UI. Your domain code should not care about what other parts of the code do, just notify them about the change in the domain data.
  2. your domain code event handler method may send asynchronous events to the UI or other modules. The domain events should be synchronous, otherwise you'd need two-phase commits to keep transactionality.

I personally like option 2 more, because it keeps the domain code cleaner and by using asynchronous communication the core and other modules will be decoupled, therefore problems in the external modules will not hinder the workings of the core. On the other hand, there may be circumstances where option 1 is more advantageous.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文