END CONVERSATION (Transact-SQL)

既存のメッセージ交換の一方の側を終了します。

トピック リンク アイコン Transact-SQL 構文表記規則

構文

END CONVERSATION conversation_handle
   [   [ WITH ERROR = failure_code DESCRIPTION = 'failure_text' ]
     | [ WITH CLEANUP ]
    ]
[ ; ]

引数

  • conversation_handle
    終了するメッセージ交換のメッセージ交換ハンドルを指定します。

  • WITH ERROR =failure_code
    エラー コードを指定します。 failure_code のデータ型は int です。 このエラー コードはユーザー定義のコードで、メッセージ交換の相手側に送信するエラー メッセージの一部となります。 このエラー コードは 0 よりも大きい値にする必要があります。

  • DESCRIPTION =failure_text
    エラー メッセージを指定します。 failure_text のデータ型は nvarchar(3000) です。 このエラー テキストはユーザー定義のテキストで、メッセージ交換の相手側に送信するエラー メッセージの一部となります。

  • WITH CLEANUP
    正常に完了できなかったメッセージ交換の一方の側のメッセージとカタログ ビュー エントリをすべて削除します。 メッセージ交換の相手側にはクリーンアップは通知されません。 Microsoft SQL Server では、メッセージ交換のエンドポイントが削除され、転送キューおよびサービス キューにあるメッセージ交換のすべてのメッセージも削除されます。 管理者は、このオプションを使用して、正常に完了できなかったメッセージ交換のメッセージを削除できます。 たとえば、リモート サービスが永久的に削除された場合、管理者は WITH CLEANUP を使ってこのサービスに対するメッセージを削除できます。 WITH CLEANUP は、Service Broker アプリケーションのコードでは使用しないでください。 受信エンドポイントでメッセージの受信を確認する前に END CONVERSATION WITH CLEANUP が実行されると、送信エンドポイントからそのメッセージが再び送信されます。 これにより、ダイアログが再実行される可能性があります。

説明

メッセージ交換を終了すると、指定した conversation_handle が属するメッセージ交換グループがロックされ、 メッセージ交換の終了時、Service Broker によってこのメッセージ交換のすべてのメッセージがサービス キューから削除されます。

メッセージ交換が終了した後、アプリケーションではそのメッセージ交換のメッセージを送受信できなくなります。 メッセージ交換を完了するには、メッセージ交換の両方の参加者が END CONVERSATION を呼び出す必要があります。 Service Broker が、メッセージ交換の相手側から終了ダイアログ メッセージまたはエラー メッセージを受信しなかった場合は、Service Broker から相手側に、メッセージ交換が終了したことが通知されます。 この場合、このメッセージ交換のメッセージ交換ハンドルが無効になる一方、メッセージ交換のエンドポイントはアクティブなまま残り、この状態はリモート サービスをホストするインスタンスからメッセージの受信確認が返されるまで継続されます。

メッセージ交換の終了ダイアログ メッセージまたはエラー メッセージが Service Broker でまだ処理されていない場合は、Service Broker からメッセージ交換のリモート側に、メッセージ交換が終了したことが通知されます。 Service Broker からリモート サービスに送信されるメッセージは、指定されるオプションによって異なります。

  • メッセージ交換がエラーなく終了し、リモート サービスへのメッセージ交換がアクティブな状態を継続していると、Service Broker からリモート サービスに、https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog のようなメッセージが送信されます。 このメッセージは、Service Broker によってメッセージ交換の順に転送キューに追加されます。 現在転送キューにあるメッセージ交換のすべてのメッセージは、このメッセージが送信されるよりも前に、Service Broker によって送信されます。

  • メッセージ交換がエラーで終了し、リモート サービスへのメッセージ交換がアクティブな状態を継続していると、Service Broker からリモート サービスに、https://schemas.microsoft.com/SQL/ServiceBroker/Error のようなメッセージが送信されます。 現在転送キューに残っているメッセージ交換のメッセージはすべて、Service Broker によって削除されます。

  • データベース管理者は WITH CLEANUP 句を使用して、正常に完了しなかったメッセージ交換のメッセージを削除できます。 このオプションでは、メッセージ交換のすべてのメッセージとカタログ ビュー エントリが削除されます。 この場合、メッセージ交換のリモート側にはメッセージ交換が終了したことが通知されません。また、アプリケーションでは送信されたが、ネットワーク経由では転送されていなかったメッセージは受信できないことがあります。 メッセージ交換が正常に完了できない場合にのみ、このオプションを使用してください。

メッセージ交換が終了した後、Transact-SQL SEND ステートメントでそのメッセージ交換ハンドルが指定されると、Transact-SQL エラーが発生します。 メッセージ交換の相手側からメッセージを受信した場合、これらのメッセージは Service Broker によって破棄されます。

メッセージ交換が終了し、そのメッセージ交換の未送信のメッセージがリモート サービス側に残っている場合、未送信のメッセージはリモート サービスによって削除されます。 これはエラーとして扱われないため、リモート サービスはメッセージの削除に関する通知を受信しません。

WITH ERROR 句のエラー コードは、正の数値で指定する必要があります。 負の数値は、Service Broker のエラー メッセージ用に予約されています。

END CONVERSATION は、ユーザー定義の関数では無効です。

権限

アクティブなメッセージ交換を終了するには、そのメッセージ交換の所有者であるか、sysadmin 固定サーバー ロールまたは db_owner 固定データベース ロールのメンバーであることが必要です。

sysadmin 固定サーバー ロールまたは db_owner 固定データベース ロールのメンバーであれば、WITH CLEANUP を使用して、既に完了したメッセージ交換のメタデータを削除できます。

使用例

A. メッセージ交換を終了する

次の例では、@dialog_handle で指定したダイアログを終了します。

END CONVERSATION @dialog_handle ;

B. メッセージ交換を終了し、エラーを返す

次の例では、処理中のステートメントでエラーがレポートされた場合に、@dialog_handle で指定したダイアログを終了し、エラーを返します。 これは簡単なエラー処理であり、アプリケーションによってはこの方法が適切でない場合があります。

DECLARE @dialog_handle UNIQUEIDENTIFIER,
        @ErrorSave INT,
        @ErrorDesc NVARCHAR(100) ;
BEGIN TRANSACTION ;

<receive and process message>

SET @ErrorSave = @@ERROR ;

IF (@ErrorSave <> 0)
  BEGIN
      ROLLBACK TRANSACTION ;
      SET @ErrorDesc = N'An error has occurred.' ;
      END CONVERSATION @dialog_handle 
      WITH ERROR = @ErrorSave DESCRIPTION = @ErrorDesc ;
  END
ELSE

COMMIT TRANSACTION ;

C. 正常に完了しなかったメッセージ交換をクリーンアップする

次の例では、@dialog_handle で指定したダイアログを終了します。 SQL Server ではサービス キューと転送キューからすべてのメッセージが直ちに削除され、リモート サービスに通知は送信されません。 このようにクリーンアップと共にダイアログを終了すると、リモート サービスに通知が送信されません。この方法は、リモート サービスで EndDialog または Error メッセージを受信できない場合にのみ使用してください。

END CONVERSATION @dialog_handle WITH CLEANUP ;

関連項目

参照

BEGIN CONVERSATION TIMER (Transact-SQL)

BEGIN DIALOG CONVERSATION (Transact-SQL)

sys.conversation_endpoints (Transact-SQL)