15

例:ビジネス ルールでは、注文が行われたときに顧客に確認メッセージ (電子メールなど) を送信する必要があると規定されています。

aNewOrderRegisteredEventがドメインからディスパッチされ、確認メッセージを送信するイベント リスナーによってピックアップされたとします。それが完了すると、他のイベント ハンドラーが例外をスローするか、他の何かがうまくいかず、作業単位がロールバックされます。ロールバックされたものについて、ユーザーに確認メッセージを送信しました。

作業単位がコミットされた後に何かをしたい場合、このような問題を解決する「cqrs」の方法は何ですか? もう 1 つの複雑な要因は、イベントの再生です。新しいビュー/プロジェクションを構築するために記録されたイベントを再生するたびに、古い確認メッセージが再送信されないようにします。

これまでの私の最高の理論: 私は魅力的な cqrs の世界を調べ始めたばかりで、これがサガとして実装されるものかどうか疑問に思っていましたか? サガが、各遷移が 1 回しか発生しないステート マシンのようなものである場合、この問題は解決すると思いますか? これがコマンドバスとドメインイベントとどのように適合するかを視覚化するのに苦労しています..

4

2 に答える 2

18
  1. イベントは、トランザクションが完了した後にのみ発生する必要があります。何か問題が発生してロールバックが発生した場合、イベントは外部の観点からは発生していません。したがって、それはまったく公開されるべきではありません。ただし、必要に応じてOrderRegistrationFailedイベントを公開できます。

  2. コマンドが正常に実行されない限り、メールを送信したくないでしょう。

    最初に、別の回答で提案されているように、コマンドハンドラーが間違った場所になるいくつかの理由: 状況によっては、コマンドハンドラーは、コマンドが最終的に成功するかどうかを判断できません。コマンド ハンドラーがメール送信を呼び出すと、コマンド ハンドラー内にプロセスの知識が入り、SRM が壊れ、ビジネス ルールとアプリケーション レイヤーが緊密に結び付きすぎます。

    メールは事後、つまりイベント ハンドラから送信する必要があります。

    再生中にこのハンドラーが起動しないようにするには、登録しないようにします。これは、アプリケーションをテストする方法と同様に機能します。実際に必要なハンドラーのみを登録します。

    • 本番システム -> すべてのイベント ハンドラを登録
    • テスト -> テスト済みのイベント ハンドラーのみを登録する
    • 再生 -> 射影/非正規化ハンドラのみを登録

別の-さらに疎結合ですが、もう少し複雑ですが-可能性は、Sagaハンドルを持ち、適切な境界付けられたコンテキストにコマンドをNewOrderRegisteredEvent発行するSendMailことです(質問のコメントでこれを指摘してくれたYves Reynhoutに感謝します)。

于 2012-06-14T12:35:38.903 に答える
3

考えられる解決策は 2 つあります

1) イベントの発行とイベントの処理 (つまり、電子メール) は、1 つのトランザクションの一部です。この場合、トランザクション フレームワークが処理します。電子メールが失敗した場合、イベントはロールバックされます。コマンドを再試行する可能性があります。これは概念的にクリーンで、簡単に考えることができます。イベントについて何か言いたいことがある人全員が発言するまで、イベントの公開は完了しません。ただし、実際には、これは通常、分散トランザクションを伴うため、苦痛になる可能性があります。これらは入手困難です。メール クライアントは、イベントを保持しているデータベースと同じトランザクションに登録できますか?

2) イベントの発行はトランザクションですが、イベント ハンドラはそれぞれ独自の方法でトランザクションを処理します。メールを送信するイベント ハンドラーは、どのイベントを見たかを追跡できます。クラッシュした場合、古いイベントを要求して処理します。人々がメールを紛失したり重複したりした場合にどれほど大きな取引になるかについて、ビジネス上の決定を下すことができます。(金銭関連の取引については、おそらく許可すべきではないというのが答えです。)

ソリューション (2) は、より疎結合のソリューションであるため、通常、DDD/CQRS サークルで推奨されているものです。ソリューション (1) は、イベント ストアとプロジェクションが単一のデータベースにあり、プロジェクションが頻繁に変更されない小規模なシステムでは非常に実用的です。解決策 (2) では、さまざまなイベント ハンドラーを独自の方法で動作させることができます。解決策 (1) は、多くの重複しない懸念が絡み合う原因となる可能性があります。この場合、注文のビジネス ルールは、電子メールで発生する多くの奇妙なことが処理されるまで完了しません。1 つには、かなり遅くなる可能性があります。

メールの送信が「イベントを見た、メールを送信した」よりも興味深いものである場合は、その通りです。あなたの手元に物語やワークフローがある可能性があります。大規模な業務における電子メールは、それ自体が複雑なシステムであることが多く、その多くを実装する必要はほとんどありません。(アプローチ (2) を使用して) 何らかのリクエスト キューに電子メールを入れることを確認する必要があるだけで、電子メール システムは再試行/バッチ処理/スパム回避/夜間作業などを行う可能性があります。

于 2012-06-14T01:35:23.453 に答える