在本课中,你将学习如何创建存储过程来处理来自 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/InitiatorService 与 AWDB/InternalAct/TargetService 之间的对话。