第 2 课:创建内部激活过程

在本课中,您将学习创建一个存储过程,以处理来自 Service Broker 队列的消息。您还将学习如何指定只要队列中有消息就激活该过程。

过程

切换到 AdventureWorks 数据库

  • 复制以下代码并将其粘贴到查询编辑器窗口中。然后,运行该代码以将上下文切换到 AdventureWorks 数据库。

    USE AdventureWorks;
    GO
    

创建内部激活过程

  • 复制以下代码并将其粘贴到查询编辑器窗口中。然后,运行该代码以创建一个存储过程。当该代码运行时,只要队列中有消息,存储过程就会持续进行接收。如果接收时间超时了,却仍没有返回消息,则存储过程将结束。如果接收到的消息为请求消息,则存储过程会返回一个答复消息。如果接收到的消息为 EndDialog 消息,则存储过程会在目标方结束会话。如果接收到的消息为 Error 消息,则存储过程会回滚该事务。

    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'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
        BEGIN
           END CONVERSATION @RecvReqDlgHandle;
        END
        ELSE IF @RecvReqMsgName =
            N'https://schemas.microsoft.com/SQL/ServiceBroker/Error'
        BEGIN
           END CONVERSATION @RecvReqDlgHandle;
        END
    
        COMMIT TRANSACTION;
    
      END
    GO
    

更改目标队列以指定内部激活

  • 复制以下代码并将其粘贴到查询编辑器窗口中。然后,运行该代码以指定 Service Broker 激活 TargetActiveProc 存储过程来处理来自 TargetQueueIntAct 的消息。只要 TargetQueueIntAct 中接收到消息,且当前无 TargetActiveProc 过程的副本在运行,Service Broker 就会运行该过程的副本。当现有副本数量无法满足传入消息数的要求时, Service Broker 会增加所运行的 TargetActiveProc 副本的数量。

    ALTER QUEUE TargetQueueIntAct
        WITH ACTIVATION
        ( STATUS = ON,
          PROCEDURE_NAME = TargetActivProc,
          MAX_QUEUE_READERS = 10,
          EXECUTE AS SELF
        );
    GO
    

后续步骤

已成功地将 AdventureWorks 配置为支持 //AWDB/InternalAct/InitiatorService//AWDB/InternalAct/TargetService 之间的会话。接下来,您将完成一个使用此配置的会话。请参阅第 3 课:启动会话并传输消息