Service Broker エラー メッセージの処理

Service Broker アプリケーションがメッセージ交換により受け取って処理する必要のあるエラー メッセージには、Service Broker を使用するアプリケーションで生成されるエラー メッセージと Service Broker で生成されるシステム メッセージの 2 種類があります。

アプリケーション エラー状況の報告

Service Broker アプリケーションは通常、異なるコンピュータ上で非同期的に実行されるコードで構成されるシステムです。アプリケーションの個々の部分は、Service Broker メッセージ交換で送信されるメッセージによって相互に通信します。Service Broker メッセージ交換の一方の側にあるアプリケーション部分は、エラー メッセージを送信して、相手側にアプリケーション エラーを報告できます。受信側のアプリケーション部分には、エラー メッセージを検出し、エラー状況を正しく処理するためのコードが必要です。

Service Broker アプリケーションは、システム定義のメッセージ型またはアプリケーション定義のメッセージ型を使用してエラーを通知できます。

システム定義エラー メッセージ

メッセージ交換を終了する必要が生じるような重大なアプリケーション エラーを報告するには、END CONVERSATION ステートメントの WITH ERROR 句を使用します。次に例を示します。

END CONVERSATION @ConversationHandle
    WITH ERROR = 1234 DESCRIPTION = "The account specified in the invoice does not exist, verify the account number."

END CONVERSATION WITH ERROR ステートメントは、次のことを行います。

  • Service Broker システム エラー メッセージを生成して、メッセージ交換のリモート側に送信します。エラー メッセージには、システム定義の http://schemas.microsoft.com/SQL/ServiceBroker/Error メッセージ型を使用します。

  • メッセージ交換のローカル側を終了させます。

Error メッセージを受信したアプリケーション部分は、必要なクリーンアップ処理を行い、メッセージ交換の受信側を終了させます。

アプリケーションは、エラーが発生したアクティブなメッセージ交換をいつでも終了できます。ただし、リモート側が既にメッセージ交換を終了している場合、Service Broker はエラー メッセージをリモート側に送信しません。代わりに、Service Broker はメッセージ交換のローカル側を終了させ、ローカル キューからメッセージ交換のメッセージをすべて削除します。

アプリケーション定義エラー メッセージ

メッセージ交換を終了するほど重大ではないアプリケーション エラーを報告するには、アプリケーション定義のエラー メッセージを使用できます。アプリケーション デザイナでは次の情報を指定できます。

  • アプリケーション エラーの通知に使用する 1 つ以上のメッセージ型。

  • これらのメッセージ型を処理するロジック。

エラー状況を検出したアプリケーション部分では次のことを行えます。

  • メッセージ交換のローカル側に必要なクリーンアップを実行する。

  • アプリケーション定義のメッセージ型を使用してメッセージを作成し、メッセージ交換で送信する。

エラー メッセージを受信するリモート側のアプリケーション部分には、エラー メッセージを識別し、受信側の接続で必要なクリーンアップ処理を行うためのコードが必要です。

エラー メッセージの処理

Service Broker メッセージ交換からメッセージを受け取るアプリケーション コードには、受け取ったエラー メッセージを処理するロジックが必要です。このコードでは、次のものを検出して処理する必要があります。

  • アプリケーション定義のエラー メッセージ型を使用してアプリケーションによって生成されるエラー メッセージ。

  • END CONVERSATION ステートメントの WITH ERROR 句を使用してアプリケーションによって生成されるエラー メッセージ。このエラー メッセージでは、http://schemas.microsoft.com/SQL/ServiceBroker/Error メッセージ型を使用し、Code 要素に正の数値が指定されます。

  • Service Broker が生成するエラー メッセージ。このエラー メッセージでは、http://schemas.microsoft.com/SQL/ServiceBroker/Error メッセージ型を使用し、Code 要素に負の数値が指定されます。Service Broker でメッセージ交換を続行できなくなるようなエラーが発生した場合に、Service Broker は Error メッセージを生成します。たとえば、交換先のサービスが現在のインスタンスに存在せず、ルーティング テーブルにサービスのエントリがないために、Service Broker がサービスを特定できない場合などです。この場合、Service Broker はメッセージ交換用の Error メッセージを作成します。

RECEIVE ステートメントによって返される結果セットには、message_type_name 列が含まれます。Service Broker メッセージを受け取るコードは、通常 message_type_name を使用して、関連付けられているメッセージ型を処理するコードに各メッセージをルーティングします。

エラーを処理するときに使用するロジックは、厳密にはアプリケーションによって異なります。たとえば、メッセージを保有して、タスクが失敗した場合の補正トランザクションを必要とするプログラムがあるとします。このプログラムは、エラーを受け取ると、処理済みのメッセージの有無をキューに問い合わせて補正トランザクションを実行し、メッセージ交換を終了します。一方、エラーが発生したことのみを記録すればよいプログラムの場合は、ログ テーブルにエラーを記録してメッセージ交換を終了します。

http://schemas.microsoft.com/SQL/ServiceBroker/Error メッセージの Code 要素には、エラー コードが含まれます。END CONVERSATION WITH ERROR を使用してアプリケーションによって生成される Error メッセージのエラー コードは正の値になります。Service Broker によって生成される Error メッセージのエラー コードは負の値になります。Service Broker で生成されるメッセージ内の Code 値は、Error メッセージの原因となったエラーの値を単に負の値に変換したものです。たとえば、XML 検証エラー (エラー コード 9615) が発生した場合、Code 要素に値 -9615 を含む Error メッセージがデータベース エンジンにより生成されます。

アプリケーションが Error 型のメッセージを受け取った場合、そのメッセージ交換ではそれ以上メッセージを送信できません。アプリケーションはエラーを処理し、そのアプリケーション側のメッセージ交換を終了します。アプリケーションがアプリケーション定義のエラー メッセージ型を受け取った場合、リモート側のアプリケーション部分でも END CONVERSATION を実行しない限り、メッセージ交換は使用できる状態です。

エラー処理ルーチンは、有害なメッセージを避けることのできる形でコーディングする必要があります。詳細については、「有害なメッセージの処理」を参照してください。