CQRSのセットベースの一貫性検証を処理する方法は?
-
04-10-2019 - |
質問
のリストを含むかなりシンプルなドメインモデルがあります Facility
総根。ドメインから提起されたイベントを処理するためにCQRとイベントバスを使用していることを考えると、セットでの検証をどのように処理できますか?たとえば、次の要件があるとします。
Facility
ユニークな名前が必要です。
クエリ側で最終的に一貫したデータベースを使用しているため、イベントプロセスがイベントを処理する時点では、そのデータが正確であることは保証されていません。
たとえば、a FacilityCreatedEvent
クエリデータベースイベントの処理キューに処理され、データベースに書き込まれるのを待っています。新しい CreateFacilityCommand
処理するドメインに送信されます。ドメインサービスは読み取りデータベースをクエリして、他にあるかどうかを確認します Facility
すでにその名前で登録されていますが、 CreateNewFacilityEvent
まだ処理されておらず、店に書かれていません。新しい CreateFacilityCommand
これで成功し、別のものを投げます FacilityCreatedEvent
イベントプロセッサがデータベースに書き込もうとすると、これは爆発し、別のものが見つかった Facility
すでにその名前で存在しています。
解決
私が一緒に行った解決策は、aを追加することでした System
電流のリストを維持できる集計ルート Facility
名前。新しいを作成するとき Facility
, 、私は使用します System
集計(1つだけ System
グローバルオブジェクト /シングルトンとして)そのための工場として。指定された施設名が既に存在する場合、検証エラーがスローされます。
これにより、ドメイン内の検証の制約が保持され、最終的に一貫したクエリストアに依存しません。
他のヒント
3つのアプローチが概説されています 最終的な一貫性と検証の設定:
- 問題がまれであるか、重要でない場合は、おそらく管理者に通知を送信することにより、管理的に対処してください。
- DuplicateFacilityNamedEmadected Eventを発送します。これにより、自動解像度プロセスが開始されます。
- ドメインイベントを聴き、名前の永続的なリストを維持することにより、使用済みの施設名を知っているサービスを維持します。新しい施設を作成する前に、最初にこのサービスを確認してください。
また、この関連する質問も参照してください。 CQRSおよびイベントソーシングを使用する場合の一意性検証
この場合、基本的に主要なキー制約を備えたSQLテーブルに挿入を行うシンプルなCRUDスタイルサービスを実装できます。
挿入物は一度だけ発生します。 1回のみ存在するのと同じ値のコマンドが複製すると、集約が到着すると、集計がサービスを呼び出し、サービスは主要なキー制約の違反のために挿入操作に失敗し、エラーが発生し、プロセス全体が失敗し、イベントはありませんクエリ側には報告なしで生成されます。おそらく、ユーザーがコマンド処理のステータスを知るためにクエリできる場所で最終的に一貫性チェックのための障害のレポートです。それを確認するには、コマンドGUIDでコマンドステータスビューモデルを何度も照会します。
明らかに、コマンドがプライマリキーチェックのためにテーブルに存在しない値を保持する場合、操作は成功します。
主要なキー制約の表はサービスとしてのみ使用する必要がありますが、イベントソーシングを実装したため、イベントを再生して、主要なキー制約の表を再構築できます。
一意性チェックはデータを書く前に行われるため、より良い方法はイベント追跡サービスを構築することです。これにより、プロセスが終了または終了したときに通知が送信されます。