【SQL Server】Service Broker(SQL Server 内置的消息队列)——1.在单个数据库建完成对话
一般来说,在SQL Server中调用存储过程,是同步的。如果一个操作比较长或者处于分布式系统,那么我们我们希望执行异步操作。这时候,可以启用SQL Server Service Broker,这是一种内置的消息传递机制,用于在数据库内部或者数据库之间进行异步通信。
消息队列概念 。消息队列在SQL Server里,是一种存储消息的结构。消息生产者将消息发送到队列中,而消息消费者则从队列中读取并处理消息。这种机制实现了应用程序组件之间的异步通信,提高了系统的可扩展性和响应能力。
基本概念
服务(Service): 一个服务代表了一个可以接收或发送消息的组件。
队列(Queue):用于存储消息。
对话(Conversation):两个服务之间的一个对话,用于发送和接收消息。
消息类型(Message Type):定义了消息的结构和内容。
前提
数据库环境:SQL Server 2019
测试数据库名:myTest
消息队列位置
接下来,我们会在同一个数据库间完成对话。
步骤
1.启用Server Broker(如果已启用,可跳过)。
2. 创建消息类型。
3. 创建协议。
4. 创建队列和服务。
5.启用会话并发发送消息。
6.接收消息。
1. 启用Server Broker;请确保数据库支持Server Broker (SQL Server 2008r2及其以上,请参考官网)。https://learn.microsoft.com/zh-cn/sql/database-engine/service-broker/lesson-1-creating-the-conversation-objects?view=sql-server-ver16
1 ALTER DATABASE myTest 2 SET ENABLE_BROKER;
查看消息队列是否启用,可以使用视图:
SELECT name, is_broker_enabled --9未启用,1:启用 FROM sys.databases WHERE name = 'myTest'; --name:对照你的数据库名
2. 创建消息类型。消息队列类型包括XML、空消息、任意数据或二进制。
| XML消息 | WELL_FORMED_XML。如果消息类型指定为XML,Service Broker会在发送消息之前验证小时是否包含有效的XML.如果消息不符合XML格式,如果不符合XML格式,Service Broker会返回错误。 |
| 空消息 | CREATE MESSAGE TYPE EmptyMessageType; 如果消息不符合XML格式,Service Broker会返回错误。 |
| 任意数据或二进制 | NONE。消息类型可以执行为不进行任何验证,即Server Broker不会验证消息内容 |
消息类型名称以URL格式指定,例如 //服务器名/数据库名/消息类型名称 ,这样能确保它们在多台计算机上名称唯一。通常我们希望传递的消息是需要经过验证的,所以启用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;
3.创建协定。 约定指定了使用此约定的会话必须将类型为 指定的发起方和接收方。
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 );
4. 创建队列和服务。需要创建发起方的队列和服务、接收方的队列和服务。在服务中,我们需要指定:服务名称、队列、约定。
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]);
以上步骤已经完成了基础数据的建设。接下来可以发送和接收请求了。
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
6. 接收请消息并结束会话。
1 DECLARE @RecvReplyMsg NVARCHAR(100); -- 返回消息 2 DECLARE @RecvReplyDlgHandle UNIQUEIDENTIFIER; -- 句柄 3 4 5 BEGIN TRANSACTION; 6 7 WAITFOR 8 ( RECEIVE TOP(1) 9 @RecvReplyDlgHandle = conversation_handle, 10 @RecvReplyMsg = message_body 11 FROM queue_reply 12 ), TIMEOUT 1000; 13 14 END CONVERSATION @RecvReplyDlgHandle; 15 16 -- 设置句柄 17 SELECT @RecvReplyMsg AS ReceivedReplyMsg; 18 19 COMMIT TRANSACTION; 20 GO
查看队列信息
SELECT * FROM queue_reply

浙公网安备 33010602011771号