構建使用異步通信的分佈式應用程序的基礎知識之一可以表示爲不要等待任何事件發生!這樣,基於SQL Service Broker的自然解決方案就是使用到達隊列的消息來激活存儲過程。SQL Service Broker和內部激活..官方教程中的無限循環是否正確?
來自Microsoft官方教程的Lesson 2: Creating an Internal Activation Procedure顯示瞭如何將存儲過程綁定到消息隊列。它也建議sp應該如何實施。
(我新的SQL,但多了一個BEGIN
的CREATE PROCEDURE... AS
後不應該在那裏,還有一END
前GO
?)
做我的理解corectly?看到我的問題下面的代碼...
CREATE PROCEDURE TargetActivProc
AS
DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg NVARCHAR(100);
DECLARE @RecvReqMsgName sysname;
WHILE (1=1)
BEGIN
BEGIN TRANSACTION;
WAITFOR
(RECEIVE TOP(1)
@RecvReqDlgHandle = conversation_handle,
@RecvReqMsg = message_body,
@RecvReqMsgName = message_type_name
FROM TargetQueueIntAct
), TIMEOUT 5000;
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
BREAK;
END
IF @RecvReqMsgName =
N'//AWDB/InternalAct/RequestMessage'
BEGIN
DECLARE @ReplyMsg NVARCHAR(100);
SELECT @ReplyMsg =
N'<ReplyMsg>Message for Initiator service.</ReplyMsg>';
SEND ON CONVERSATION @RecvReqDlgHandle
MESSAGE TYPE
[//AWDB/InternalAct/ReplyMessage]
(@ReplyMsg);
END
ELSE IF @RecvReqMsgName =
N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @RecvReqDlgHandle;
END
ELSE IF @RecvReqMsgName =
N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
END CONVERSATION @RecvReqDlgHandle;
END
COMMIT TRANSACTION;
END
GO
當消息到達時,該過程被調用,並進入「無限」循環。實際上,由於BREAK
之後ROLLBACK
沒有數據到達時(在TIMEOUT
之後),所以循環不是無限的。
如果數據到達,則跳過BREAK
。如果預期的消息到達,則回覆。如果接收到...EndDialog
或...Error
消息,則執行END CONVERSATION
。在這裏還可以觀察到其他類型的消息嗎?
當一些消息到達(並被處理)時,事務被提交。
但爲什麼現在循環?是否打算處理由於過去的通信線斷開而滯留在隊列中的其他消息?或者因爲有更多的消息立刻出現,無法如此快速處理?
當另一條消息排隊並且存儲過程仍在運行時會發生什麼情況。是另一個工作過程分配給它的處理?可以並行啓動另一個存儲過程嗎?如果是,那爲什麼是循環?
感謝您的幫助,彼得堡
對不起,延遲。我沒有時間去嘗試,但是。但這對我來說是有價值的信息。 – pepr 2012-08-17 11:08:28