web-dev-qa-db-ja.com

コマンドに複数のハンドラーを使用することの落とし穴はありますか?

モノリスを分割することを検討しています。これを行うために、サブドメインの有力な候補のように見えるいくつかのビジネス領域を特定し、それらのサブドメイン間で機能を分割する方法を理解しようとしています。

ドメインはスポーツリーグ管理ソフトウェアです。

いくつかのサブドメインを暫定的に特定しました。そのうちの3つは、スケジュール(フィクスチャの時期と場所)、アカウンティング(フィクスチャに対して各チームに請求する金額)、および競争管理(チームAがフィクスチャを獲得した場合、ポイント数)です。割り当てられているかなど)。

分割しようとしている機能の例は、2つのチーム間のスポーツの試合であるフィクスチャの削除です。

フィクスチャを削除する場合、これら3つのサブドメインすべてが関与する必要がある場合があります。具体的には、削除によって以前に使用されていたスペースが解放され、関係するチームにフィクスチャの料金が請求されなくなり、フィクスチャの結果がなくなったため、リーグの順位を更新する必要があります。

同様に、3つのサブドメインはすべて、フィクスチャを実際に削除できるかどうかについて発言権を持つ場合があります。まあ、おそらくスケジュールではないかもしれませんが、会計では「そのフィクスチャを削除できません。チームAはすでに支払いました。代わりにキャンセルする必要があります」と表示され、競争管理は「そのフィクスチャを削除できません。すでに削除しました。このフィクスチャの結果に基づいて、次のフィクスチャの参加者を計算しました。」.

各サブドメインが特定のコマンドのバリデーターとハンドラーを提供できるアーキテクチャをスケッチしました。したがって、コマンドバスはすべてのサブドメインからすべてのバリデーターを見つけ、それらをループし、トランザクションのコンテキスト内で、プロセスが正常に実行されるかどうかを確認します。すべてが「GO!」と言う場合、バスはすべてのコマンドハンドラーをループしてコマンドを渡し、最後にいずれかのハンドラーのエラーが原因でトランザクションをロールバックするか、トランザクションをコミットして必要なイベントを発行します。出版。

ここまでは順調ですね。私だけがそのようなアプローチを推奨する人に出くわしませんでした。すべての推奨事項は、コマンドには1つのコマンドハンドラのみが必要であり、他のサブドメインで後続の処理を実行するために、またはコマンドバスに配置する追加のコマンドを作成するために使用する必要があるということです。どちらが問題ありませんが、サブドメイン3のイベントでのみ認識される検証エラーのためにコマンドを処理できない場合はどうでしょうか。

ここで間違った木を吠えていますか?私たちはサガについて話しているのですか?またはアプリケーションサービス?または、複数のコマンドバリデーターとハンドラーの概念が実際に実行可能に見えますか?私たちが見つけていない落とし穴を誰かが提案できますか?

ご意見ありがとうございます!

[〜#〜]編集[〜#〜]

これはマルチテナント型のアプリではなく、各顧客が独自のサイトを持っているため、マシンを水平方向に追加することでスケーリングが実現されることに注意してください。つまり、より多くの顧客=別のサーバーです。すべてのサービスは同じマシンで実行され、同じトランザクションに参加できます。異なるマシンで異なるサービス/マイクロサービスが実行されているレイアウトに必ずしも移動する必要はありません。各サブドメインのロジックをコードの個別のセクションにカプセル化して、新しい開発者が簡単に理解して理解できるようにするだけです。維持する。

4

イベントソーシングは、トランザクションや途中で方向を変えるのが得意ではありません。それは、メガホンを使ってオフィススペースに足を踏み入れて事実や変化を発表するようなもので、部屋の誰もが自分の結論を引き出すことができます。 「顧客が新しい住所に移動した」イベントがあったとしましょう。誰もが自分のシステムを更新します。失敗した場合、エラー処理は、成功するまで操作を再試行することで構成される可能性があります。実際には前の状態に戻ることはありません。疎結合であるため、メッセージの受信者が誰なのかわからないため、他のすべての参加者にトランザクションをロールバックするように伝える方法はありません。

Railsまたは佐賀のアプローチを試すことができます。コーディネーターは操作を開始する前にすべての承認を収集しますが、チェックの時間と実行の時間の間にギャップがあるため、実際にはトランザクションではありません。

前提条件(フィクスチャが14日以上ある場合は削除する)でコマンドを送信して送信できますが、サービス間で異なるサービスの内部状態をコード化しないように十分注意する必要があります。

マイクロサービスの移行によって導入された新しい問題を解決するのが難しすぎる場合、境界のあるコンテキストが正しく描画されないか、現在の設計のサービスでさえ、計画どおりに分割できない可能性があります。

削除は必須ですか?私が見た多くのシステムでは、(オブジェクトを削除するために)完全削除を許可していませんでした。オブジェクトを「削除済み」状態に移動することはできますが、オブジェクトをシステムから本当に削除することはできません。

3
Martin K