0

私は CQRS と結果整合性モデルを初めて使用するので、これがばかげた質問である場合はご容赦ください。

始めたばかりなので、ローカル メモリ内に CommandBus と EventPublisher があります。私のイベントは再生目的で RavenDB データベースに永続化されますが、イベントは発行され、ハンドラーはローカルで呼び出されます (NServiceBus などを介して外部でキューに入れられることはありません)。EventPublisher はイベントを非同期に発行します (Task.Factory.StartNew のように)。

イベントに依存関係がある場合があります (たとえば、OrderShipmentStatusUpdated イベントを ReadModel に正しく処理する前に、OrderReceived イベントを ReadModel に処理する必要があります)。

この種のシナリオをどのように処理できますか? サガを使う?上記のような単純なメモリ内モデルで Sagas を使用するにはどうすればよいでしょうか。イベントを「延期」することは受け入れられると考えられますか (おそらく、それを延期としてマークし、延期されたすべてのイベントを「たまに」再処理しようとします)。

これに対処するためのいくつかの戦略は何ですか?

ありがとうございました。

4

5 に答える 5

3

ほとんどの場合、再試行を行うキューは、このような問題を解決します。前提条件が満たされていないために、ハンドラー/集約/デノーマライザーがメッセージを処理できない場合は、ハードに失敗します。次に、このメッセージが再び表示されるまで、キューからさらにいくつかのメッセージを処理します。メッセージが 3 回以上失敗した場合は、さらに分析するためにエラーキューに破棄します。

それが予想されるワークフローであり、実際に待つ必要がある場合 - DDD/イベント ソーシングでモデリングしていない場合は、Saga を作成します。DDD/イベント ソーシングを使用してモデル化する場合 - 集約は、ほとんどの場合、そのような機能をカバーします。

于 2013-05-01T15:22:36.207 に答える
2

問題は、なぜイベントが順不同で到着するのかということです。

「技術的な力」が原因である場合は、これに対処するインフラストラクチャを確認できますが、これには通常、本格的なメッセージ キューが必要です。

「ビジネス プロセス」が原因でメッセージ/イベントが同期していない場合は、Sagas/ProcessManager を確認できます。イベント ストアを queue として使用する Greg Young のアプローチをご覧ください。

イベントの延期に関する質問に答えるには: 考えられるのは、集約を使用して必要な順序をモデル化することにより、単純化されたアプローチを使用することです。イベントを消費し、条件が満たされた場合にのみ読み取り側に通知します。ビューは、集計によって「検証」されたイベントのみを投影します。モデルで暗黙の概念を明示的にする利点があります。欠点は、より多くのイベントが生成されることです。(はい、何も無料ではありません)

これに関するRinat Abdullin のアプローチをご覧ください。これは古いが興味深い投稿であり、おそらくビーイング・ザ・ワーストのポッドキャストを参照してください.

于 2013-04-29T08:53:37.800 に答える
2

ILICHに同意します。

イベントが発生し、読み取りモデルはそれについて報告するだけです。読み取りモデルは、イベントを検証する立場にあるべきではありません。

新しいサガを作成するよりも、ドメイン モデルに配送ロジックを含める方が簡単な場合があります。

小規模なプロジェクトを「ごまかす」もう 1 つの方法は、イベントをトリガーとして使用してイベントストアから読み取ることです。したがって、読み取りモデルがイベント通知を受け取ると、イベントストアからすべての「新しい」イベントをロードする必要があります。これにより、輸送中に何も失われないことが保証され、バスの使用目的が簡素化されます。

プロトタイピング段階では、読み取りモデルを自由に吹き飛ばして、自動的に再構築することもできます。

特定の読み取りモデルを処理するために消費された最新のイベントを反映する「ジョブ履歴」の小さなテーブルを保持しています。読み取りモデルのスキーマを変更したい場合は、適切なレコードを削除するだけです。

于 2013-04-29T14:23:44.083 に答える
1

同期/非同期イベント発行の問題について:

指定された を、イベント ストアに永続化された独自のコミット ID を持つオブジェクトでラップすることにより、オブジェクトを非同期に処理DomainEventsし、内でを同期的に発行することができました。ラッピングは、特定の集計への変更が要求されたときにメモリ内集計を追跡するために発生します。EventCommitEventCommitDomainEventsEventCommitUnitOfWork

読み取り側では、コミット ID を使用して、イベントをハンドラーにディスパッチする前に、デキュー プロセスで直接正しい順序を確認できます。

于 2014-07-08T07:33:12.227 に答える