使用MDA时,是否应区分幂等事件处理程序和非幂等事件处理程序? [英] When using MDA, should you differentiate between idempotent and non-idempotent event handlers?
问题描述
该问题假定使用事件源。
The question assumes the use of Event Sourcing.
通过重播事件重建当前状态时,事件处理程序应该是幂等的。例如,当用户成功更新其用户名时,可能会发出 UsernameUpdated
事件,该事件包含 newUsername
字符串属性。重建当前状态时,适当的事件处理程序将接收 UsernameUpdated
事件,并在<$ c $上设置 username
属性。 c> User 对象指向 UsernameUpdated
事件对象的 newUsername
属性。换句话说,多次处理同一条消息始终会产生相同的结果。
When rebuilding current state by replaying events, event handlers should be idempotent. For example, when a user successfully updates their username, a UsernameUpdated
event might be emitted, the event containing a newUsername
string property. When rebuilding current state, the appropriate event handler receives the UsernameUpdated
event and sets the username
property on the User
object to the newUsername
property of the UsernameUpdated
event object. In other words, the handling of the same message multiple times always yields the same result.
但是,与外部服务集成时,这种事件处理程序如何工作?例如,如果用户想重设密码,则 User
对象可能会发出 PasswordResetRequested
事件,该事件将得到处理通过向第三方发出发送短信命令的一部分代码。现在,当重建应用程序时,我们不想重新发送此SMS。最好如何避免这种情况?
However, how does such an event handler work when integrating with external services? For example, if the user wants to reset their password, the User
object might emit a PasswordResetRequested
event, which is handled by a portion of code that issues a 3rd party with a command to send an SMS. Now when the application is rebuilt, we do NOT want to re-send this SMS. How is this situation best avoided?
推荐答案
交互中涉及两个消息:命令和事件。
There are two messages involved in the interaction: commands and events.
我不认为消息传递基础结构中的系统消息与域事件相同。命令消息的处理应该是幂等的。通常不需要事件处理程序。
I do not regard the system messages in a messaging infrastructure the same as domain events. Command message handling should be idempotent. Event handlers typically would not need to be.
在您的方案中,我可以告诉聚合根100次以更新用户名:
In your scenario I could tell the aggregate root 100 times to update the user name:
public UserNameChanged ChangeUserName(string username, IServiceBus serviceBus)
{
if (_username.Equals(username))
{
return null;
}
serviceBus.Send(new SendEMailCommand(*data*));
return On(new UserNameChanged{ Username = userName});
}
public UserNameChanged On(UserNameChanged @event)
{
_username = @event.UserName;
return @event;
}
以上代码将导致单个事件,因此对其进行重构不会产生任何结果重复处理。即使我们有100个 UserNameChanged
事件,结果也将与 On
方法不执行任何处理一样。我想记住要记住的一点是,命令端会完成所有 real 工作,而事件端仅用于 来更改对象的状态。
The above code would result in a single event so reconstituting it would not produce any duplicate processing. Even if we had 100 UserNameChanged
events the result would still be the same as the On
method does not perform any processing. I guess the point to remember is that the command side does all the real work and the event side is used only to change the state of the object.
上面的内容不一定是我实现消息传递的方式,但确实说明了这一概念。
The above isn't necessarily how I would implement the messaging but it does demonstrate the concept.
这篇关于使用MDA时,是否应区分幂等事件处理程序和非幂等事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!