この分散システムの設計をどの程度制御できるかにもよりますが、一歩下がって、これまで問題を絞り込んできたソリューションのドメインの外で考えてみると、そのアーキテクチャにとってより良い場合があります。「主な問題」は、分散サービスが共通データベースを介して相互に通信する方法を見つけることであることがわかりました。多分それはあなたが挑戦すべき考えです。
これらのコンポーネントが通信するための潜在的な方法は多数あります。設計目標が待ち時間を短縮してポーリングを回避することである場合、実際には、この作業項目の完了を通知する必要があるサービスに通知するのが正しい方法である可能性があります。それをすぐに。ただし、将来、このシステムのスループットを向上させる必要がある場合は、作業項目を一括で処理し、代わりに情報をポーリングすることが唯一の実行可能なオプションになる可能性があります。これが、私の回答をもう少し一般的に表現し、この分散システムの設計をより抽象的に議論することにした理由でもあります。
この検討の後も回答が変わらず、すぐに通知が必要な場合は、作業項目を処理するコンポーネントから、通知が必要なコンポーネントに通知することを検討してください。分散システムの一般的な設計原則として、特定のデータ セットに対して最も信頼できるコンポーネントを、そのデータに関する要求に応答するコンポーネントにすることが最善です。この場合、取得しているデータは作業項目の完了ステータスであるため、これに対応する最適なコンポーネントは、作業項目を完了しているコンポーネントです。そのコンポーネントが、呼び出し元のクライアントとコンポーネントにその完了を通知する方がよい場合があります。ここだ』
ただし、コンポーネント間の結合を減らしたり、他のコンポーネントと直接通信するためのアクセスがないなど、そのような呼び出しをしたくない正当な理由があると思います。Windows の MSMQ や Windows Azure のキューなど、このような通知を可能にする多くの通信プリミティブがあります。また、システム内の通信が 3 番目のコンポーネントに依存しているなどの理由もあり、システムの可用性が低下し、停止につながる可能性があります。ここで自問したい質問は次のとおりです。「信頼性と可用性の観点から、このシステムの設計上の優先事項は何ですか?」
したがって、最初に解決しようとする主な問題は、もう少し抽象的なものだと思います。この分散システムのコンポーネントが通信するためのインターフェースはどのように見えるべきか?
このすべての後、これらのコンポーネント間の通信インターフェイスを SQL データベースにすることに決めたままの場合は、SQL で INSERT および UPDATE トリガーを使用して調べることができます。これらのコマンドの構文を簡単に調べて、実行されるストアド プロシージャを指定できます。これらのストアド プロシージャでは、新しい行の完了フラグを確認し、場合によっては日付で確認する行数を制限するか、最後に処理された作業項目の ID を取得する必要があります。次に、他のコンポーネントに通知するには、組み込みのストアド プロシージャを使用して、XP_cmdshell
Windows でコマンド ラインを実行することもできます。実行するコマンドは、タスクの完了のためにサービスに ping を送信する単純なツールである可能性があります。
SQL クエリ通知を使用するというあなたの提案を最初に見落としてしまい申し訳ありません。これも実行可能な方法であり、Service Broker コンポーネントを介して機能します。SqlCommand
通常データベースにクエリを実行するかのようにを定義し、これを のインスタンスに渡しSqlDependency
、 というイベントをサブスクライブしOnChange
ます。を実行するとSqlCommand
、 に追加したイベント ハンドラが呼び出されますOnChange
。
ただし、イベント ハンドラーに渡されるオブジェクトからデータベースへの正確な変更を取得する方法がわからないSqlNotificationEventArgs
ため、クエリは、アプリケーションが作業項目が完了したことをいつでも通知できるように十分に具体的である必要がある場合があります。または、正確に何が変更されたかを知ることができるように、通知を受けるたびに、アプリケーションからデータベースへの別のラウンドトリップを実行する必要がある場合があります。