2011-08-03 113 views
2

我們有一個應用程序,它使用Service Broker在SQL Server中創建隊列和服務來處理數據庫通信。應用程序使用這些服務並正確發送/接收消息,但我現在要測試此應用程序的初始化階段(它創建代理以及在幕後工作的存儲過程)。基本上,我需要以一定的頻率放棄經紀人元素,現在它真的很慢。如何快速關閉Microsoft SQL Server Service Broker的所有元素?

我能夠改變應用程序創建代理元素的方式(如果有幫助的話) - 但這個問題更關係到關閉所有東西。

我使用關閉代理的代碼是:

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發起方]」。是否有更快捷的方法關閉並刪除服務代理的全部或部分元素?

謝謝!

== ==更新

好吧,我花了一些時間,但下面的答案解決了問題。我想澄清其他人可能會遇到的問題。

我的應用程序正確關閉了所有服務,隊列,合同和消息。由於應用程序中存在大量來自應用程序中的bug的公開對話,因此關閉服務一直在持續進行。正在創建這些談話中,用於發送消息,然後關閉:

END CONVERSATION @conversation with cleanup 

的「與清理」位即將關閉的談話(認爲的本地端,它允許服務器清除任何的對話內容可能在另一端出錯)。它不會關閉發送服務的另一端,因此對話仍處於打開狀態。正常會話應該結束:

END CONVERSATION @conversation 

修復了應用程序錯誤。但是,我在數據庫中發生了數百萬的破壞對話。我可以像普通人一樣放棄數據庫,或者我可以嘗試弄清楚如何關閉它們。要逐一關閉它們:

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 

這需要每個連接幾ms(對數百萬非常慢)。如果我想很快就全部關閉,使用下面的答案,運行修改命令:不讓它們確保提交

ALTER DATABASE [" + target.getTargetDbName() + "] SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 

的與回滾立即使所有連接的下降。該文件說'所有不完整的事務將被回滾,並且AdventureWorks2008R2示例數據庫的任何其他連接都將立即斷開。「 http://msdn.microsoft.com/en-us/library/bb522682.aspx

現在服務正在迅速下降,錯誤和開放連接消失了。

回答

5

原因很慢可能是因爲這些元素被鎖定了SCH-S鎖,因爲它們正在使用中,從而阻止了您的drop語句。典型的罪魁禍首是在後臺運行的激活程序。可以通過檢查Activity Monitor阻止原因或查看sys.dm_exec_requests來快速調查此問題。運行激活的程序可以在sys.dm_broker_activated_tasks中看到。

作爲一種變通方法,你可以嘗試ALTER DATABASE SET NEW_BROKER,將放棄所有現有的對話,而不是排隊/服務/合同/消息類型。它也將改變當前數據庫service_broker_instance_id(重要的,如果你在使用路由的話)。通過刪除所有會話,激活的過程應該自行關閉(如果它們被正確寫入)。

但我會建議不同的方法。而不是讓你的測試一遍又一遍重複使用相同的數據庫,並從「關機」階段處理所有的假故障,你應該總是從一個乾淨的數據庫開始,在一個乾淨的數據庫運行部署腳本。這樣你就不需要'刪除'代碼。請參閱Version Control and your Database。我們使用乾淨數據庫的數據庫備份,並始終從此開始,恢復並部署您的應用程序,然後運行您的驗證測試。

+0

感謝所有好的建議,有一些隊列線程沒有得到正確關閉,所以我能夠找到一種方法來處理開放連接。按照數據庫備份 - 好主意,但我們希望測試能夠在任何數據庫上運行,而不是專門的測試。謝謝。 – Noah

相關問題