构建使用异步通信的分布式应用程序的基础知识之一可以表示为不要等待任何事件发生!这样,基于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