この単純化された例について考えてみましょう。オンラインチケット販売Webサイトでは、チケットには時間とともに変動する変動価格があります。
ユーザーはticketsを検索します。必要なチケットを見つけたら、[購入]をクリックして見積を発行します。引用は永続化され、電子メールで送信されるロケーターを所有しています。見積もりページが開き、彼が支払う金額の内訳と、支払うボタンが表示されます。この時点で、チケットはまだ他の人が利用できます。ユーザーが「今すぐ支払う」をクリックすると、支払いプロセスが開始され、購入注文が発行され、詳細が表示されます。
注文書が支払われるとき、見積ステータスは「承諾済み」に設定され、注文書を参照する必要があります。チケットのステータスは「販売済み」に設定されます。
要件に従って、これはアトミックな方法で発生する必要があります。つまり、承認されていない見積もりを参照する有料の注文書、または販売されていないチケットをいつでも受け入れることはできません。基本的に、結果整合性は許可されません。
2つの大きな集合体、Quote
とPurchaseOrder
があります。 1つ目は内訳の計算、税金などを管理します。2つ目は見積もりの支払いの詳細、支払いイベントの発生などを管理します。問題は、今のところ、チケット、見積もり全体でトランザクションを使用する必要があるようです。そして最後に支払われたときに注文書。
「トランザクションが集計の境界を越えてはならない」ルールを尊重してこれをどのようにモデル化できますか?
複数の集約を生成するトランザクションを使用せずに、必要なことを正確に実行するプロセスマネージャ/サガが必要です。
基本的に、佐賀は支払いが始まる直前にチケットをreserve
、支払いが成功した後にmarkTicketAsSold
、または支払いが失敗した後にreleaseTheReservation
を行います。
このプロセスと、reserved
またはsold
チケットを再びreserved
にすることができない不変条件は、システムが穴として常に正しい状態であることを保証します。
要件に従って、これはアトミックな方法で発生する必要があります。つまり、承認されていない見積もりを参照する有料の購入注文や、販売されていないチケットをいつでも受け入れることはできません。基本的に、結果整合性は許可されません。
これは有効な不変式ではないようです。不変条件は、「販売済みのチケットは再販売できません」である必要があります。 ビジネスインバリアントを慎重に定義するは、集計の境界を設計し、長時間実行されるプロセスを正しくモデル化するのに役立ちます。