【问题标题】:SQL Service Broker and Internal Activation.. Is the infinite loop in the official tutorial correct?SQL Service Broker 和内部激活.. 官方教程中的无限循环是否正确?
【发布时间】:2012-08-13 23:04:22
【问题描述】:

构建使用异步通信的分布式应用程序的基础之一可以表示为不要主动等待任何事件!这样,基于SQL Service Broker的自然解决方案是使用通过到达队列的消息激活存储过程。

微软官方教程中的Lesson 2: Creating an Internal Activation Procedure 展示了如何将存储过程绑定到消息队列。它还提出了应该如何实现 sp 的方式

(我是 SQL 新手。但在CREATE PROCEDURE... AS 之后不应该有一个BEGIN,在GO 之前应该有一个END?)

我理解正确吗?在代码下方查看我的问题...

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

当消息到达时,过程被调用,并进入“无限”循环。实际上,循环不是无限的,因为ROLLBACK之后的BREAK在没有数据到达时(TIMEOUT之后)。

如果数据到达,则跳过BREAK。如果预期的消息到达,则将回复发回。如果收到...EndDialog...Error 消息,则执行END CONVERSATION。这里还可以观察到其他类型的消息吗?

当一些消息到达(并被处理)时,事务被提交。

但是为什么现在循环呢?是否打算处理过去因为通信线路中断而卡在队列中的其他消息?还是因为一次性收到的消息较多,无法这么快处理?

当另一条消息排队并且存储过程仍在运行时会发生什么。是否为其处理分配了另一个工作流程?可以并行启动另一个存储过程吗?如果是,那为什么是循环?

谢谢你的帮助,彼得

【问题讨论】:

    标签: sql-server service-broker


    【解决方案1】:

    内部激活不像触发器。具体来说,激活的过程不会为每条到达的消息启动。相反,当 SSB 基础设施正在监视进度时,当有一些事情要处理并且应该连续(在循环中)使消息出队时启动该过程,并且如果有必要,启动第二个过程以提供帮助,直到指定的最大值。见Understanding Queue Monitors

    并不是严格要求在激活的过程中有一个循环,即使没有循环也应该可以正常工作。循环应该在非常繁忙的环境中表现更好。另请参阅这个旧的MSDN discussion

    【讨论】:

    • 抱歉耽搁了。我还没有时间尝试。但这对我来说是很有价值的信息。
    猜你喜欢
    • 2014-05-15
    • 2015-12-10
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多