第 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 课:启动会话并传输消息。