Service Broker を使用して SQL Server でキューとサービスを作成し、db 通信を処理するアプリがあります。アプリはこれらのサービスを使用し、メッセージを正しく送受信しますが、このアプリの初期化フェーズをテストしたいと思います (ブローカーと、舞台裏で動作するストアド プロシージャを作成します)。基本的に、ブローカ要素をある程度の頻度で削除する必要がありますが、現在は非常に遅いです。
それが役立つ場合、アプリがブローカー要素を作成する方法を変更できますが、この質問はすべてをシャットダウンすることに関連しています。
ブローカーをシャットダウンするために使用しているコードは次のとおりです。
receive * from [dbo].[notify_initiator_queue]
alter queue [dbo].[notify_initiator_queue] with status = OFF
drop service [//DBNotifyService-Initiator]
drop queue [dbo].[notify_initiator_queue]
drop message types, contacts, etc...
これは、「ドロップ サービス [//XF/DBNotifyService-Initiator]」でしばらくハングします。Service Broker のすべてまたは一部の要素を閉じて削除するより迅速な方法はありますか?
ありがとう!
==アップデート==
わかりました、少し時間がかかりましたが、以下の答えで問題は解決しました。問題を抱えている可能性のある他の人のために明確にしたかったのです。
私のアプリは、すべてのサービス、キュー、コントラクト、およびメッセージを正しくシャットダウンしました。アプリのバグによる未解決の会話がたくさんあったため、サービスをシャットダウンするのに非常に時間がかかりました。これらの会話は作成され、メッセージの送信に使用され、次のように閉じられました。
END CONVERSATION @conversation with cleanup
「with cleanup」ビットは、会話のローカル エンドのみを閉じます (これにより、サーバーは相手側でエラーになった可能性のある会話をクリーンアップできると考えてください)。送信サービスの相手側を閉じないため、会話は開いたままになっていました。通常の会話は終了する必要があります。
END CONVERSATION @conversation
これにより、アプリのバグが修正されました。ただし、データベースには数百万の壊れた会話がありました。通常の人のようにデータベースをドロップするか、それらを閉じる方法を見つけようとすることができます。それらをすべて 1 つずつ閉じるには、次の手順が必要です。
declare @conversation uniqueidentifier
while exists (select top 1 conversation_handle from sys.transmission_queue )
begin
set @conversation = (select top 1 conversation_handle from sys.transmission_queue )
end conversation @conversation with cleanup
end
これには、接続ごとに数ミリ秒かかります (数百万の場合は非常に遅くなります)。それらをすべて非常に迅速に閉じたい場合は、以下の回答を使用して、変更されたコマンドを実行します。
ALTER DATABASE [" + target.getTargetDbName() + "] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
with rollback immediate は、コミットを保証することなく、すべての接続をドロップします。ドキュメントには、「すべての不完全なトランザクションはロールバックされ、AdventureWorks2008R2 サンプル データベースへのその他の接続は直ちに切断される」と記載されています。 http://msdn.microsoft.com/en-us/library/bb522682.aspx
バグと開いている接続がなくなったため、サービスは現在非常に急速に低下しています。