使用领域事件模式
我一直在尝试在 udi dahan 所描述的新项目中实现此模式。
我喜欢 if 的想法,但我还不太确定在什么情况下应该应用它(对于这个东西来说是新的......)。
例如,假设我有一个事件 OnUserCreated。我希望其中一个处理程序向用户发送一封确认电子邮件。但是,如果事件被触发,电子邮件被发送,然后提交事务时出错并且数据永远不会保存到数据库中,该怎么办?该模式适用于这种情况吗?我读过人们说不,但我做过的一些项目实际上就是这样做的。或者这是我只应该用来加载和更新其他实体的东西...另一方面,我读到有人说操作所需的关联实体应该已经加载,所以我不应该从数据库中加载它们事件。
I've been attempting to implement this pattern in a new project as described by udi dahan.
I like the idea of if but I'm not quite sure yet in what cases it should be applied for (new to this stuff...).
For example lets say I have an event OnUserCreated. I want one of the handlers to send a confirmation email to the user. But what if the event get fired the email gets sent and then there is an error committing the transaction and the data never gets saved to the database. Is the pattern applicable in this situation? I've read people say no but some projects I've gone over do in fact do it like that. Or is this something I should only be using to load and update other entities...on the other hand I read someone say that the associated entities needed for the operation should already be loaded so I should not be loading them from the database in an event.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这当然取决于您选择如何实施您的系统。
您可以在此处考虑多种选择:
1。两阶段提交
在进行两阶段提交时,基本上每个处理程序都包含 3 个方法:一种用于准备,一种用于提交,一种用于回滚。
对于所有事件处理程序,首先调用Prepare。如果这些都没有报告问题,则调用所有处理程序的 Commit() 方法。如果其中任何一个报告了问题——尽管Prepare()调用没有报告问题——那么对于所有已经执行了Commit()的处理程序,您可以调用它们的Rollback()方法。
2.内部和外部事件处理程序
另一种选择是分离事件处理程序。您可以发布一个事件,例如 UserCreated,该事件由首先参与事务的事件处理程序处理。该事件作为事务的一部分存储在数据库中。然后,您可以拥有仅对已存储在数据库中的事件做出反应的外部事件处理程序 - 例如您的电子邮件发件人。这些只能在提交初始事务后调用。
我相信您可以想出更多方法来处理您的具体情况。
It of course depends on how you choose to implement your system.
You can consider multiple options here:
1. Two-phase commit
When doing a two-phase commit, basically every handler contains 3 methods: one to Prepare, one to Commit and one to Roll Back.
For all event handlers, the Prepare is called first. If none of those reports a problem, then all the handlers' Commit() methods are called. If any of those reports a problem -- despite no issues being reported by the Prepare() calls -- then for all the handlers whose Commit() has already been executed, you call their Rollback() methods.
2. Internal and External event handlers
Another option is to make a separation of event handlers. You may publish an event, such as UserCreated, which is processed by event handlers that take part in the transaction first. The event gets stored in the DB as part of the transaction. Then you can have external event handlers which react only to events that are already stored in the DB -- such as your email sender. These can only get called after the initial transaction is committed.
I'm sure you can think of more ways to handle your specific scenario.
使用域事件允许您将某些操作(发送电子邮件)移至业务事务(创建用户)之外。事件的发布与数据库事务在同一事务中登记,因此如果数据库事务失败,事件将不会被发布。使用持久消息队列系统 ( msmq ) 可保证如果事件已发布,则处理程序最终将被执行。
您的流程应如下所示:
作为旁注,尝试在命名事件时不使用“On”前缀,因为在句子中使用它们更容易。
Using domain events allows you to move some actions ( sending of email ) outside the business transaction ( creating the user ). The publishing of the events is enlisted in the same transaction as your db transaction so if the db transaction fails the events will not be published. Using a durable message queuing system ( msmq ) guarantees that if the event was published the handler will eventually be executed.
Your flow should look something like this:
As a side note try to name your events without the "On" prefix, since it's easier to use them in sentences.