1

この質問は、イベント ソーシングの使用を前提としています。

イベントを再生して現在の状態を再構築する場合、イベント ハンドラーはべき等である必要があります。たとえば、ユーザーが自分のユーザー名を正常に更新すると、文字列プロパティUsernameUpdatedを含むイベントが発行される場合があります。newUsername現在の状態を再構築するとき、適切なイベント ハンドラーがイベントを受け取り、オブジェクトのプロパティをイベント オブジェクトのプロパティにUsernameUpdated設定します。つまり、同じメッセージを複数回処理すると、常に同じ結果が得られます。usernameUsernewUsernameUsernameUpdated

しかし、外部サービスと統合する場合、そのようなイベント ハンドラーはどのように機能するのでしょうか? たとえば、ユーザーがパスワードをリセットしたい場合、UserオブジェクトはPasswordResetRequestedイベントを発行する可能性があります。これは、SMS を送信するコマンドをサードパーティに発行するコードの一部によって処理されます。アプリケーションが再構築されたときに、この SMS を再送信したくありません。この状況をどのように回避するのが最善ですか?

4

3 に答える 3

2

対話には、コマンドとイベントの2 つのメッセージが含まれます。

私は、メッセージング インフラストラクチャのシステム メッセージをドメイン イベントと同じとは考えていません。コマンド メッセージの処理は冪等でなければなりません。通常、イベント ハンドラーは必要ありません。

あなたのシナリオでは、集約ルートにユーザー名を更新するように 100 回伝えることができます。

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メソッドが処理を実行しないため、結果は同じです。覚えておくべきポイントは、コマンド側がすべての実際の作業を行い、イベント側はオブジェクトの状態を変更するためだけに使用されるということです。

上記は、必ずしもメッセージを実装する方法ではありませんが、概念を示しています。

于 2015-12-14T06:25:56.933 に答える
0

ここでは、2 つの別々の概念が混在していると思います。1 つ目は、ハンドラがすべてエンティティ自体の内部メソッドであるオブジェクトを再構築することです。Axon フレームワークのサンプル コード

public class MyAggregateRoot extends AbstractAnnotatedAggregateRoot {

@AggregateIdentifier
private String aggregateIdentifier;
private String someProperty;

public MyAggregateRoot(String id) {
    apply(new MyAggregateCreatedEvent(id));
}

// constructor needed for reconstruction
protected MyAggregateRoot() {
}

@EventSourcingHandler
private void handleMyAggregateCreatedEvent(MyAggregateCreatedEvent event) {
    // make sure identifier is always initialized properly
    this.aggregateIdentifier = event.getMyAggregateIdentifier();
    // do something with someProperty
}

}

外部 API と対話するコードを集約のメソッド内に配置しないことは確かです。

2 つ目は、あなたが話している問題を引き起こす可能性のある制限されたコンテキストでイベントを再生することです。ケースによっては、イベント ハンドラーをクラスターに分割する必要がある場合があります。

この点については、Axon フレームワークのドキュメントを参照して、問題とその解決策をよりよく理解してください。

クラスターでのイベントの再生

于 2015-12-13T12:40:42.963 に答える