5

こんにちは、結果整合性を取得する方法がわからない次のシナリオがあります。

  1. ユーザー 1 は、タスク ベースの UI を使用して顧客名を変更します
  2. アグリゲートでの App Service 呼び出し操作
  3. 顧客名が変更された場合のアグリゲート ファイア イベント
  4. bus は nservicebus を使用してメッセージを送信します
  5. NServicebus サービスの停止
  6. ユーザー 2 は集約を取得し、変更アドレスを呼び出します
  7. 呼び出された集計操作
  8. 発生したドメイン イベント
  9. バスに乗せられたメッセージ
  10. バスの再起動
  11. メッセージ 2 が最初にピックアップされました
  12. メッセージ 2 が処理され、その他の境界付きコンテキストが新しいアドレスで更新されました
  13. メッセージ 1 がピックアップされましたが、順序が間違っています
  14. 今、何が起きた

13 では、イベントで集約のバージョンを渡すと楽観的同時実行エラーが発生しますか?

その場合、Message 1 new が他のコンテキストのオブジェクトに適用されます。一貫性を維持するにはどうすればよいでしょうか。

これが、ドメインにイベントを適用することを妨げている問題です。すべてのヘルプ歓迎。

本質的なアイデアは、別のコンテキストで別の集約を更新することです。私はこれの並行性の技術にこだわっています。

コマンドハンドラやコマンドがバスにプッシュされるという意味で、イベントソーシングや CQRS は使用していません。変更したくない既存の設計があるため、非同期で発生させたいのはイベント処理だけです。

ブレア

4

4 に答える 4

3

通常、メッセージをキューに入れます。それらがキューに入っている場合は、適切な順序になります。サービスバスでの注文をサポートしていないものを使用する場合は、イベントにシーケンス番号を追加して、反対側がイベントを適切に並べ替えられるようにします。TCPは1981年以来これを行っていますhttp://www.ietf.org/rfc/rfc793.txt :)

于 2013-03-02T12:08:12.297 に答える
0

おっと:あなたの例では実際に2つの異なるタスクを使用していることに気付きました(顧客名と顧客住所)。もちろん、順序は重要ではないため、これは問題ではありません。しかし、あなたの意図が同じタイプの変更を2つ持つことだった場合に備えて、私の答えを残します.

いつものように、いくつかの質問/問題が頭に浮かびます:

1 つには、2 人のユーザーが同時にアドレスを更新でき、処理の順序がランダムになる可能性があるため、この例ではエンドポイントが失敗する必要はありません。したがって、どちらが正しい住所なのかという問題になります。そのため、それを解決するには、さらに多くの分析が必要です1 つには、2 人のユーザーが同時に (またはその近くで) 住所を更新するほど頻繁に顧客が移動することはないと想定できると思います --- :)

それでも、最初のアドレスが正しいのかもしれません。

このようなシナリオでは、同時実行性またはその他の許容範囲が問題であるかどうかを特定する必要があると思います。そのため、アドレスは 1 日に 1 回しか変更されず、その他の変更には別の操作が必要になる場合があります。したがって、いくつかの例外処理がオプションになります。

これを技術レベルに落とし込んで解決しようとするのではなく、プロセス/ビジネスへの影響を検討する必要があります。

簡単な解決策として、メッセージの送信日を特定のタイプの最後の操作日に一致させます。そのためChangeAddressCommand、メッセージを処理するときに現在のものと比較しLastAddressChange、メッセージが最終変更日より前に送信された場合は拒否できます。

于 2013-03-02T17:45:57.943 に答える
0

NServiceBus に関する同様の問題については、こちらで説明しています。OP は、IBus.HandleCurrentMessageLater() を使用して、他のメッセージが到着するまでスピンすることを提案しています。これは機能しますが、どれくらい待たなければならないかわからないため、問題が発生する可能性があります.

より複雑なオプションは、サガを使用することです特定のバージョンにつながるすべてのメッセージが到着するまで待機します。この場合、順序付けはバージョンに基づいて行われ、集約バージョンのすべての変更が他の BC に発行された場合にのみ可能です。メッセージ 1 がアグリゲートのバージョン 2 で操作されたとします。次に、集約のバージョンをインクリメントし、バージョン 2 で動作したことを示すイベントを発行します。メッセージ 2 は、集約のバージョン 3 で動作し、バージョン 3 で動作したことを示すイベントを発行します。他の BC の NServiceBus エンドポイントがメッセージ 1 の前にメッセージ 2 を受信すると、最後に受信したメッセージが集約のバージョン 1 で操作されていることがわかっているため、バージョン 2 で操作されたメッセージが必要です。次のメッセージを待っているサガを開始します。メッセージ 1 を受信すると、サガはメッセージ 1 を適用してからメッセージ 2 を適用し、サガの状態を解放します。順序付けにバージョンを使用できない場合は、別の順序付け戦略を使用できます。

于 2013-03-02T18:10:18.110 に答える
0

これによると、あなたは自問する必要があります:

障害が発生すると、ビジネスにどのような影響がありますか?

現在のケースでは、この問題は 100 万回のリクエストで 1 回発生します。両方の要求を有効として受け入れたとしても、ビジネスに大きな影響を与えるとは思いません。

于 2014-05-24T10:13:25.580 に答える