目標:継続的に生成されたレコードを中央SQLに確実に転送します。
要約:衛星は中央にその側の最新のデータは何かを尋ねる必要があり、それからそれは継続的に新しいデータを送信する予定です。
サテライトSQLサーバーは(物理的な実稼働マシンに関連して)時々(再)起動される場合があり、中央のSQLマシンはより長く実行される可能性がありますが、ダウンタイムも発生する可能性があります。回線はほとんど信頼できますが、誰にもわかりません...接続の問題はSQL ServerServiceBrokerによって自然に解決されると思います。ただし、最初のハンドシェイクとデータ送信の問題を解決する必要があります。プロトコルを設計する必要がありますが、SSBの知識はまだ不十分です。
SSBを使用したコミュニケーションの基本を理解していただければ幸いです。
各作業項目は、それぞれの会話から始める必要があります。プロデューサー(イニシエーター)はダイアログを開始し、作業項目を説明するメッセージを送信してから、コミットします。コンシューマー(ターゲット)はメッセージを受信し(またはアクティブ化され)、ペイロードを検査して作業項目の詳細を理解し、作業を実行してから、ダイアログを終了してコミットします。結果のEndDialogメッセージはイニシエーターサービスキューに返送され、イニシエーターキューでアクティブ化されたプロシージャは、イニシエーター側のダイアログを終了することでそれに応答します。
... Remus Rusanuによる(興味がある場合は、彼の以前の回答で詳細を参照してください)。
このようなXMLメッセージ(ここでは複数行の文字列)としてレコードを送信したいと思います
<row a="1" b="11" c="111" />
<row a="2" b="22" c="222" />
<row a="3" b="33" c="333" />
<row a="4" b="44" c="444" />
そして、XMLメッセージから情報を取得するためのの書き方SELECT
をすでに学びました。
通信: SQLサーバー間の通信メカニズムがアクティブ化されたとしましょう...
サテライトSQLは新しいデータを取得しましたが、どういうわけか、サテライトとセントラルの間に保留中のメッセージがないことを認識しています。ただし、どのデータがすでにセントラルに送信されているかもわかりません。したがって、中央に最後に利用可能なデータは何かを尋ねる必要があります。
私が
END CONVERSATION
正しく理解していれば、このコマンドは一種の空のメッセージのみを送信しますN'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
。このため、セントラルはおそらく、のReplyMessage
前に回答を含む私のタイプを送信する必要がありEND CONVERSATION
ます。その間、衛星はおそらく非同期で動作するために何もしないはずです(つまり、送信後に待機します
RequestMessage
)。ReplyMessage
到着すると、次のような衛星手順がアクティブになります。- メッセージを受信し、必要な情報を取得し、
- EndDialogメッセージを受信し、衛星側で前のダイアログを終了します。
- セントラル(XML文字列形式)に送信するデータを準備します。
- 新しいダイアログを開き、
- 準備されたデータを送信し、
ReplyMessage
別の人が到着するまで休眠状態になります。
セントラルも同様に動作する必要があります。
RequestMessage
到着すると、次のような中央手順がアクティブになります。- リクエストメッセージを受信し、
- XML情報を抽出し、中央データベースを更新します。
- 衛星で利用可能な最後のデータに関する情報を取得し、
- を形成して送信し
ReplyMessage
ます - 中央側でダイアログを終了します。
これまでのところ、私の見解は正しいですか?
さて、私にはよくわからない詳細がいくつかあります。人の手を触れずに動作する堅牢なものにしたいので、メカニズムがインストールされたときに自動的に起動する必要があります。通信は常に衛星によって開始されるべきです(衛星が機能している、あるいは存在しているとしても、中央は知らないかもしれません)。
衛星は、中央で収集されるレコードを構築するために処理される生データによって起動されるトリガーをすでに使用しています。このようにして、トリガーはどういうわけか中央への衛星の最初のSSB要求を開始することができます。だが...
- トリガーは、衛星と中央の間に保留中の通信がないことをどのように確認できますか?衛星は常にイニシエーターであるため、質問は次のように定式化することもできます...トリガーは、衛星が何らかの待機をしているかどうかをどのように確認できますか
ReplyMessage
?または、衛星と中央衛星の間に開いたダイアログがあることを知る方法はありますか?- 会話がない場合、トリガーはデータレコード(ローカルテーブルに格納されている)を形成し、通信プロセスを開始できます(上記のポイント1を参照)。
- 会話がある場合、トリガーは後で送信されるレコードのみを形成し、他には何も行われません。データは
ReplyMessage
、アクティブ化された手順によって取得されたときに送信されます(上記のポイント3を参照)。
- サテライトを休止状態にすると(上記のポイント3の最後の箇条書きを参照)、メッセージキューに他のメッセージがない可能性があり(ループで処理されるものがない)、アクティブ化された手順が自然に終了することを意味します。しかし、ここで正しく考えているかどうかはわかりません。コメントしてもらえますか?
- 何も壊れておらず、データが十分に速く生成されている場合、衛星と中央衛星は常に何かを交換する必要があります。このように、トリガーは通信を開始しようとしないでください。
- アクティブ化された衛星手順によってセントラルに送信されるものが他にない場合(実際にはアクティブではありません)、またはシステムが何らかの方法で再起動された場合(ダイアログがまだ存在しない場合)、トリガーは通信プロセスを開始します。しかし、どうすればそれを行うことができますか?トリガーは単に
RequestMessage
中央に送信する必要がありますか?(このようにするReplyMessage
と、衛星手順がアクティブになり、処理するものができるまで手順が続行されます。) - たとえば、ここでの
RequestMessage
手段はいくつかのデータであり、それらを処理し、最後のものを返信します(または、次に送信する必要があるもの、または中央から推奨される次のアクションは、ビジネスロジックによって異なりますが、ここではおそらく重要ではありません)。他に何が必要かわからないという意味で、空のXMLを送信しても大丈夫ですか?教えてください。RequestMessage
最初の更新-以下のRemusRusanuの回答に基づいています。
これがおしゃべりなプロトコルになることに同意する必要があります。さらに、レコードは実際の環境からの温度サンプルとして作成され、サンプリングの頻度はかなり低くなります。これは、複雑なプロトコルは、すべてを再起動するという特別な場合にのみ役立つ可能性があることを意味します。
ただし、会話を永久に開いたままにしておく必要がある場合は、ダイアログハンドルの一意の識別子を保持するか、構成テーブルに永続的に保存する必要があります。または、コードにハードワイヤードすることもできます。トリガーはその場でレコードをすぐに送信し、セントラルは単にを送信しませんReplyMessage
。それが正しいか?そのような報道は、事実上独白と見なすことができますか?
この質問を適度に短くするための2番目の更新。