CQRS イベントソーシングは、コマンドの送信時に EventStore からユーザー名が一意かどうかを確認します。質問する

CQRS イベントソーシングは、コマンドの送信時に EventStore からユーザー名が一意かどうかを確認します。質問する

EventSourcing は、特定の一意の EntityID がある場合には完璧に機能しますが、eventStore から特定の EntityId 以外の情報を取得しようとすると、困難が生じます。

私は EventSourcing で CQRS を使用しています。イベント ソーシングの一環として、イベントを列 (EntityID (uniqueKey)、EventType、EventObject (例: UserAdded)) として SQL テーブルに保存しています。

したがって、EventObject を保存するときは、DotNet オブジェクトをシリアル化して SQL に保存するだけです。したがって、UserAdded イベントに関連するすべての詳細は xml 形式になります。私の懸念は、データベース内に存在する userName が一意であることを確認したいということです。

したがって、AddUser コマンドを作成するときに、特定の userName がすでに eventStore に存在するかどうかを EventStore(sql db) に照会する必要があります。そのためには、イベント ストア内のすべての UserAdded/UserEdited イベントをシリアル化し、要求されたユーザー名がイベント ストアに存在するかどうかを確認する必要があります。

ただし、CQRS コマンドの一部は、競合状態が原因でクエリが許可されない可能性があります。

そこで、AddUser コマンドを送信する前に、eventStore を照会してすべてのイベント (UserAdded) をシリアル化してすべての UserNames を取得し、ユーザー名を取得し、要求されたユーザー名が一意である場合はコマンドを実行し、そうでない場合はユーザー名が既に存在するという例外をスローするようにしました。

上記のアプローチと同様に、データベース全体をクエリする必要があり、1 日に数十万のイベントが発生する可能性があります。そのため、クエリ/デシリアライゼーションの実行には長い時間がかかり、パフォーマンスの問題が発生します。

すべてのユーザー名をeventStoreから取得するか、他の方法でユーザー名を一意に保つためのより良いアプローチ/提案を探しています

ベストアンサー1

したがって、クライアント (コマンドを発行するもの) は、送信したコマンドが実行されることを確信する必要があります。そのためには、RegisterUserCommand を送信する前に、その電子メール アドレスに他のユーザーが登録されていないことを確認する必要があります。つまり、検証を実行するのはクライアントであり、ドメインやドメインを取り巻くアプリケーション サービスではありません。

からhttp://cqrs.nu/よくある質問

これは、書き込み側でクロス集計操作を明示的に実行していないため、よく発生する質問です。ただし、いくつかのオプションがあります。

すでに割り当てられているユーザー名の読み取り側を作成します。ユーザーが名前を入力すると、クライアントが読み取り側を対話的に照会するようにします。

重複したユーザー名で作成されたアカウントをフラグ付けして無効にするためのリアクティブ サガを作成します。(まったくの偶然か、悪意によるものか、またはクライアントの不具合によるものかは関係ありません。)

最終的な一貫性が十分速くない場合は、書き込み側、つまり、すでに割り当てられた名前の小さなローカル読み取り側にテーブルを追加することを検討してください。集計トランザクションに、そのテーブルへの挿入が含まれるようにします。

おすすめ記事