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

适用于SQL ServerAzure SQL 托管实例

在本课中,你将学习如何创建存储过程来处理来自 Service Broker 队列的消息。 你还将了解如何指定在队列中存在消息时激活该过程。

过程

注意

本文中的代码示例是使用 AdventureWorks2025 示例数据库进行测试的,可以从 Microsoft SQL Server 示例和社区项目 主页下载该数据库。

切换到 AdventureWorks 数据库

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

USE AdventureWorks2022;
GO

创建内部激活存储过程

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

CREATE PROCEDURE TargetActiveProc
AS
DECLARE @RecvReqDlgHandle AS UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg AS NVARCHAR (100);
DECLARE @RecvReqMsgName AS 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;
                BREAK;
            END
        IF @RecvReqMsgName = N'//AWDB/InternalAct/RequestMessage'
            BEGIN
                DECLARE @ReplyMsg AS 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 中收到消息,Service Broker 就运行 TargetActiveProc 的副本,并且该过程的副本尚未运行。 每当现有副本不跟上传入消息数时,Service Broker 将运行 TargetActiveProc 的额外副本。

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

后续步骤

已成功配置为 AdventureWorks2025 支持 AWDB/InternalAct/InitiatorServiceAWDB/InternalAct/TargetService 之间的对话。