私はまだCQRSスタイルのアーキテクチャに関連する基本的な(そして解決された)問題に苦労しています:
集約ルートのセットに依存するビジネスルールをどのように実装しますか?
例として、予約アプリケーションを取り上げます。コンサートのチケット、映画の座席、レストランのテーブルを予約できる場合があります。いずれの場合も、販売される「アイテム」の数は限られています。
イベントや場所がとても人気があると想像してみましょう。新しいイベントや時間帯の販売が開始されると、予約は非常に迅速に到着し始めます。おそらく1秒あたりの数が多くなります。
クエリ側では、大規模な拡張が可能であり、予約はキューに入れられ、自律コンポーネントによって非同期的に処理されます。最初は、予約コマンドをキューから削除するときに受け入れますが、ある時点で、残りのコマンドを拒否し始める必要があります。
限界に達したとき、どうやって知ることができますか?
予約コマンドごとに、ある種の店舗に問い合わせて、リクエストに対応できるかどうかを判断する必要があります。これは、その時点ですでに受け取った予約の数を知る必要があることを意味します。
ただし、ドメインストアがWindows Azureテーブルストレージなどの非リレーショナルデータストアである場合、SELECT COUNT(*) FROM ...
1つのオプションは、次のように、現在のカウントを追跡するだけの個別の集約ルートを保持することです。
- AR:予約(誰?何人?)
- AR:イベント/タイムスロット/日付(集計数)
2番目の集約ルートは最初の集約ルートの非正規化された集約ですが、基盤となるデータストアがトランザクションをサポートしていない場合、大量のシナリオでこれらが同期しなくなる可能性が非常に高くなります(これが私たちが試みていることです)そもそもアドレス)。
考えられる解決策の1つは、予約コマンドの処理をシリアル化して、一度に1つだけが処理されるようにすることですが、これはスケーラビリティ(および冗長性)の目標に反します。
このようなシナリオは、標準の「在庫切れ」シナリオを思い出させますが、違いは、予約をバックオーダーにうまく入れることができないことです。イベントが完売すると完売するため、補償措置がどうなるかわかりません。
そのようなシナリオをどのように処理しますか?