【SQL Server】Service Broker(SQL Server 内置的消息队列)——2.实现内部激活
前面我已经能够通过SQL Server Broker完成简单的内置消息队列。接下来,我们要了解内部激活流程。
是什么意思呢?我们在需要的时候发送了消息队列?那什么时候接收呢?
1. 使用SQL Server Agnent,创建作业,设置了作业调度。在作业中调度消息队列。(SQL Server作业调度:https://www.cnblogs.com/luyj00436/p/18724042)
2. 完成接收消息的存储过程。在接收的队列中,设置激活的存储过程。
回顾基础的消息队里,关键代码如下:
1. 创建消息类型(XML)
1 CREATE MESSAGE TYPE [//AWD/myTest/msgType_request_xml] VALIDATION=WELL_FORMED_XML; 2 CREATE MESSAGE TYPE [//AWD/myTest/msgType_reply_xml] VALIDATION=WELL_FORMED_XML;
2. 创建协定
1 CREATE CONTRACT [//AWD/myTest/contract_default] ( 2 [//AWD/myTest/msgType_request_xml] SENT BY INITIATOR, 3 [//AWD/myTest/msgType_reply_xml] SENT BY TARGET 4 );
3. 创建队列和服务
1 -- 发送方方队列和服务(由于未指定约定名称,其他服务不可将此服务用作目标服务) 2 CREATE QUEUE queue_request; 3 CREATE SERVICE [//AWD/myTest/service_request] 4 ON QUEUE queue_request; 5 -- 接收方队列和服务 6 CREATE QUEUE queue_reply; 7 CREATE SERVICE [//AWD/myTest/service_reply] 8 ON QUEUE queue_reply 9 ([//AWD/myTest/contract_default]);
4. 启用会话并发送消息
1 DECLARE @InitDlgHandle UNIQUEIDENTIFIER; -- 发送句柄 2 DECLARE @RequestMsg NVARCHAR(100); -- 发送消息 3 4 BEGIN TRANSACTION; 5 6 BEGIN DIALOG @InitDlgHandle 7 FROM SERVICE 8 [//AWD/myTest/service_request] -- 发送方服务请求 9 TO SERVICE 10 '//AWD/myTest/service_reply' -- 接收方服务请求(注意要写正确) 11 ON CONTRACT 12 [//AWD/myTest/contract_default] -- 约定 13 WITH 14 ENCRYPTION = OFF; 15 16 SELECT @RequestMsg = 17 N'<RequestMsg>Message for Target service.</RequestMsg>'; 18 19 SEND ON CONVERSATION @InitDlgHandle 20 MESSAGE TYPE 21 [//AWD/myTest/msgType_request_xml] -- 消息类型 22 (@RequestMsg); 23 24 SELECT @RequestMsg AS SentRequestMsg; 25 26 COMMIT TRANSACTION; 27 GO
5. 接收消息并结束会话。
1 DECLARE @InitDlgHandle UNIQUEIDENTIFIER; -- 发送句柄 2 DECLARE @RequestMsg NVARCHAR(100); -- 发送消息 3 4 BEGIN TRANSACTION; 5 6 BEGIN DIALOG @InitDlgHandle 7 FROM SERVICE 8 [//AWD/myTest/service_request] -- 发送方服务请求 9 TO SERVICE 10 '//AWD/myTest/service_reply' -- 接收方服务请求(注意要写正确) 11 ON CONTRACT 12 [//AWD/myTest/contract_default] -- 约定 13 WITH 14 ENCRYPTION = OFF; 15 16 SELECT @RequestMsg = 17 N'<RequestMsg>Message for Target service.</RequestMsg>'; 18 19 SEND ON CONVERSATION @InitDlgHandle 20 MESSAGE TYPE 21 [//AWD/myTest/msgType_request_xml] -- 消息类型 22 (@RequestMsg); 23 24 SELECT @RequestMsg AS SentRequestMsg; 25 26 COMMIT TRANSACTION; 27 GO
实现内部激活
实现内部激活。消息、协定、服务、队列的方法与前文一致。现在已创建内如如下:
消息类型:[//AWD/myTest/msgType_request_xml] 和 [//AWD/myTest/msgType_reply_xml]
协定:[//AWD/myTest/contract_default]
队列:QUEUE queue_request 和QUEUE queue_reply
服务:[//AWD/myTest/service_reply] 和[//AWD/myTest/service_reply]
1. 新建接收消息的存储过程。只要队列中有消息,存储过程就会持续接收和处理( 这里直接抄官网,队列名称等可能不一致)。
1 CREATE PROCEDURE TargetActiveProc 2 AS 3 DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; 4 DECLARE @RecvReqMsg NVARCHAR(100); 5 DECLARE @RecvReqMsgName sysname; 6 7 WHILE (1=1) 8 BEGIN 9 10 BEGIN TRANSACTION; 11 12 WAITFOR 13 ( RECEIVE TOP(1) 14 @RecvReqDlgHandle = conversation_handle, 15 @RecvReqMsg = message_body, 16 @RecvReqMsgName = message_type_name 17 FROM TargetQueueIntAct 18 ), TIMEOUT 5000; 19 20 IF (@@ROWCOUNT = 0) 21 BEGIN 22 ROLLBACK TRANSACTION; 23 BREAK; 24 END 25 26 IF @RecvReqMsgName = 27 N'//AWDB/InternalAct/RequestMessage' 28 BEGIN 29 DECLARE @ReplyMsg NVARCHAR(100); 30 SELECT @ReplyMsg = 31 N'<ReplyMsg>Message for Initiator service.</ReplyMsg>'; 32 33 SEND ON CONVERSATION @RecvReqDlgHandle 34 MESSAGE TYPE 35 [//AWDB/InternalAct/ReplyMessage] 36 (@ReplyMsg); 37 END 38 ELSE IF @RecvReqMsgName = 39 N'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 40 BEGIN 41 END CONVERSATION @RecvReqDlgHandle; 42 END 43 ELSE IF @RecvReqMsgName = 44 N'https://schemas.microsoft.com/SQL/ServiceBroker/Error' 45 BEGIN 46 END CONVERSATION @RecvReqDlgHandle; 47 END 48 49 COMMIT TRANSACTION; 50 51 END 52 GO
2. 更改目标队列,以指定激活。
1 ALTER QUEUE TargetQueueIntAct 2 WITH ACTIVATION 3 ( STATUS = ON, 4 PROCEDURE_NAME = TargetActiveProc, 5 MAX_QUEUE_READERS = 10, 6 EXECUTE AS SELF 7 ); 8 GO
MAX_QUEUE_READERS 指:MAX_QUEUE_READERS 是 SQL Server 中 Service Broker 的一个属性,用于限制同时读取队列消息的进程数量。当你在 CREATE QUEUE 或 ALTER QUEUE 语句中设置 MAX_QUEUE_READERS 时,可以指定一个最大值,该值表示同时可以激活的最大队列读取器数量。如果激活任务的数量超过这个限制,Service Broker 会忽略 MAX_QUEUE_READERS 设置,继续运行额外的激活任务1。

浙公网安备 33010602011771号