使用MDA时,是否应区分幂等事件处理程序和非幂等事件处理程序? [英] When using MDA, should you differentiate between idempotent and non-idempotent event handlers?

查看:128
本文介绍了使用MDA时,是否应区分幂等事件处理程序和非幂等事件处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该问题假定使用事件源。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆