【SQL Server】Service Broker——在单个数据库建完成对话

news/2025/1/20 13:40:54/文章来源:https://www.cnblogs.com/luyj00436/p/18681002

一般来说,在SQL Server中调用存储过程,是同步的。如果一个操作比较长,那么我们我们希望执行异步操作。

消息队列概念 。消息队列在SQL Server李,是一种存储消息的结构。消息生产者将消息发送到队列中,而消息消费者则从队列中读取并处理消息。这种机制实现了应用程序组件之间的异步通信,提高了系统的可扩展性和响应能力。

消息队列位置

 接下来,我们会在同一个数据库间完成对话。

步骤

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

 ALTER DATABASE AdventureWorks2008R2SET ENABLE_BROKER;

 2. 创建消息类型。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行代码为会话创建消息类型。 由于通常在数据库引擎的多个实例间引用 Service Broker 对象,因而大多数 Service Broker 对象的名称都是以 URI 格式指定的。 这有助于确保它们在多台计算机上是唯一的。 这两种消息类型都指定 Service Broker 将只验证消息是否是格式正确的 XML 文档,并且指定 Service Broker 将不按照特定架构验证 XM

1 CREATE MESSAGE TYPE
2            [//AWDB/1DBSample/RequestMessage]
3            VALIDATION = WELL_FORMED_XML;
4     CREATE MESSAGE TYPE
5            [//AWDB/1DBSample/ReplyMessage]
6            VALIDATION = WELL_FORMED_XML;
7     GO

 3.创建协定。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行代码为会话创建约定。 约定指定了使用此约定的会话必须将类型为 /AWDB/1DBSample/RequestMessage 的消息从发起方发送到目标以及将类型为 //AWDB/1DBSample/ReplyMessage 的消息从目标发送到发起方。

1 CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
2           ([//AWDB/1DBSample/RequestMessage]
3            SENT BY INITIATOR,
4            [//AWDB/1DBSample/ReplyMessage]
5            SENT BY TARGET
6           );
7     GO

 4.创建目标队列和服务。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行代码以创建要用于目标的队列和服务。 由于队列是从相同的数据库以类似于表和视图的方式引用的,因而队列名称的格式也类似于表名称或视图名称。 CREATE SERVICE 语句将服务与 TargetQueue1DB 相关联。 因此,所有发送给此服务的消息将接收到 TargetQueue1DB 中。 CREATE SERVICE 还指定只有使用先前创建的 //AWDB/1DBSample/SampleContract 的会话才能将该服务用作目标服务。

1 CREATE QUEUE TargetQueue1DB;
2 
3     CREATE SERVICE
4            [//AWDB/1DBSample/TargetService]
5            ON QUEUE TargetQueue1DB
6            ([//AWDB/1DBSample/SampleContract]);
7     GO

 5.创建发起方队列和服务。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行代码以创建要用于发起方的队列和服务。 由于未指定约定名称,因而其他服务不可将此服务用作目标服务。

1 CREATE QUEUE InitiatorQueue1DB;
2 
3     CREATE SERVICE
4            [//AWDB/1DBSample/InitiatorService]
5            ON QUEUE InitiatorQueue1DB;
6     GO

 6.启用会话并发动请求。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行该代码以启动会话并向 //AWDB/1DBSample/TargetService 发送请求消息。 该代码必须在一个块中运行,因为是使用变量将对话句柄从 BEGIN DIALOG 语句传递到 SEND 语句。 批处理运行 BEGIN DIALOG 语句,以启动会话。 它会生成一个请求消息,然后使用 SEND 语句中的对话句柄发送该会话的请求消息。 最后一条 SELECT 语句显示已发送消息的文本。

 1 DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
 2     DECLARE @RequestMsg NVARCHAR(100);
 3 
 4     BEGIN TRANSACTION;
 5 
 6     BEGIN DIALOG @InitDlgHandle
 7          FROM SERVICE
 8           [//AWDB/1DBSample/InitiatorService]
 9          TO SERVICE
10           N'//AWDB/1DBSample/TargetService'
11          ON CONTRACT
12           [//AWDB/1DBSample/SampleContract]
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          [//AWDB/1DBSample/RequestMessage]
22          (@RequestMsg);
23 
24     SELECT @RequestMsg AS SentRequestMsg;
25 
26     COMMIT TRANSACTION;
27     GO

 7. 接收请求并发送答复。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行该代码以接收来自 TargetQueue1DB 的答复消息,并将答复消息发回给发起方。 RECEIVE 语句可检索该请求消息。 以下 SELECT 语句将显示文本,以便您可以验证它是否与上一步中发送的消息相同。 IF 语句测试所接收的消息是否是请求消息类型,并测试是否使用了 SEND 语句将答复消息发送回发起方。 END CONVERSATION 语句用于结束会话的目标端。 最后一条 SELECT 语句显示答复消息的文本。

 1 DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
 2     DECLARE @RecvReqMsg NVARCHAR(100);
 3     DECLARE @RecvReqMsgName sysname;
 4 
 5     BEGIN TRANSACTION;
 6 
 7     WAITFOR
 8     ( RECEIVE TOP(1)
 9         @RecvReqDlgHandle = conversation_handle,
10         @RecvReqMsg = message_body,
11         @RecvReqMsgName = message_type_name
12       FROM TargetQueue1DB
13     ), TIMEOUT 1000;
14 
15     SELECT @RecvReqMsg AS ReceivedRequestMsg;
16 
17     IF @RecvReqMsgName =
18        N'//AWDB/1DBSample/RequestMessage'
19     BEGIN
20          DECLARE @ReplyMsg NVARCHAR(100);
21          SELECT @ReplyMsg =
22          N'<ReplyMsg>Message for Initiator service.</ReplyMsg>';
23 
24          SEND ON CONVERSATION @RecvReqDlgHandle
25               MESSAGE TYPE
26               [//AWDB/1DBSample/ReplyMessage]
27               (@ReplyMsg);
28 
29          END CONVERSATION @RecvReqDlgHandle;
30     END
31 
32     SELECT @ReplyMsg AS SentReplyMsg;
33 
34     COMMIT TRANSACTION;
35     GO

 8.接收答复并结束会话。

 1 DECLARE @RecvReplyMsg NVARCHAR(100);
 2     DECLARE @RecvReplyDlgHandle UNIQUEIDENTIFIER;
 3 
 4     BEGIN TRANSACTION;
 5 
 6     WAITFOR
 7     ( RECEIVE TOP(1)
 8         @RecvReplyDlgHandle = conversation_handle,
 9         @RecvReplyMsg = message_body
10       FROM InitiatorQueue1DB
11     ), TIMEOUT 1000;
12 
13     END CONVERSATION @RecvReplyDlgHandle;
14 
15     SELECT @RecvReplyMsg AS ReceivedReplyMsg;
16 
17     COMMIT TRANSACTION;
18     GO

 9.删除会话对象。复制以下代码并将其粘贴到查询编辑器窗口中。 然后,运行代码以删除用于支持该会话的对象

 1 IF EXISTS (SELECT * FROM sys.services
 2                WHERE name =
 3                N'//AWDB/1DBSample/TargetService')
 4          DROP SERVICE
 5          [//AWDB/1DBSample/TargetService];
 6 
 7     IF EXISTS (SELECT * FROM sys.service_queues
 8                WHERE name = N'TargetQueue1DB')
 9          DROP QUEUE TargetQueue1DB;
10 
11     -- Drop the initiator queue and service if they already exist.
12     IF EXISTS (SELECT * FROM sys.services
13                WHERE name =
14                N'//AWDB/1DBSample/InitiatorService')
15          DROP SERVICE
16          [//AWDB/1DBSample/InitiatorService];
17 
18     IF EXISTS (SELECT * FROM sys.service_queues
19                WHERE name = N'InitiatorQueue1DB')
20          DROP QUEUE InitiatorQueue1DB;
21 
22     IF EXISTS (SELECT * FROM sys.service_contracts
23                WHERE name =
24                N'//AWDB/1DBSample/SampleContract')
25          DROP CONTRACT
26          [//AWDB/1DBSample/SampleContract];
27 
28     IF EXISTS (SELECT * FROM sys.service_message_types
29                WHERE name =
30                N'//AWDB/1DBSample/RequestMessage')
31          DROP MESSAGE TYPE
32          [//AWDB/1DBSample/RequestMessage];
33 
34     IF EXISTS (SELECT * FROM sys.service_message_types
35                WHERE name =
36                N'//AWDB/1DBSample/ReplyMessage')
37          DROP MESSAGE TYPE
38          [//AWDB/1DBSample/ReplyMessage];
39     GO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/872124.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uos 开发笔记

version GLIBCXX_3.4.26 not found的问题解决 一查看是否有这个库/lib64/libstdc++.so.6 二查看这个库/lib64/libstdc++.so.6中的的GLIBCXX的支持的版本 经查看是环境里已经有这个库,并且是个软连接,软连接到libstdc++.so.6.0.19查看这个库/lib64/libstdc++.so.6中的的GLIBC…

C#/.NET/.NET Core技术前沿周刊 | 第 22 期(2025年1.13-1.19)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿、推荐或自荐优质文章、项目、学习资源等…

映射注入

一、前言 在所有先前的实现中,私有内存类型都用于在执行期间存储有效负载。私有内存是使用 VirtualAlloc 或 VirtualAllocEx 分配的,如下图所示可以看到内存类型属于Private二、映射内存注入 分配私有内存的过程因被恶意软件广泛使用而受到安全解决方案的高度监控。为了避免使…

攀高行为检测识别摄像机

攀高行为检测识别摄像机具有高清晰度和远程监控功能。通过高清晰度的摄像头捕捉到工作人员在高空作业中的实时图像,并通过远程监控系统进行数据传输和处理。管理人员可以随时随地查看工作人员的操作情况,及时发现异常行为并采取相应措施。攀高行为检测识别摄像机支持多种智能…

升降梯人数统计识别摄像机

升降梯人数统计识别摄像机具有高效的图像识别功能。通过高清晰度的摄像头捕捉到升降梯内乘客的图像,并通过图像识别技术进行快速准确的人数统计。并通过智能算法对数据进行融合分析。通过多源数据融合分析,可以更加全面准确地评估升降梯内乘客流量情况。升降梯人数统计识别摄…

边坡监测预警摄像机

边坡监测预警摄像机是一种结合了摄像技术和智能算法的设备,能够实时监测边坡的变化情况,并通过分析和识别地表位移、裂缝扩展等特征来提供监测和预警服务。这种摄像机在土木工程、地质灾害防治、城市规划等领域有着广泛的应用,可以帮助管理人员及时发现潜在风险并采取相应措…

防疲劳驾驶摄像头

防疲劳驾驶摄像头具有高清晰度和远程监控功能。通过高清晰度的摄像头实时捕捉到驾驶员的面部表情和眼睛活动情况,并通过远程监控系统进行数据传输和处理。当系统检测到驾驶员出现打哈欠、频繁眨眼等疲劳征兆时,会自动触发警示系统,提醒司机注意休息或换班。防疲劳驾驶摄像头…

vue3.5保证你看得明明白白

子组件中设置默认属性 <template><div class="child-page"><h1>我是子组件</h1><h3>{{ total }}</h3><h3>{{ userInfo }} </h3></div> </template><script setup> // 在<script setup>defi…

工作时间离岗智能识别监测系统

工作时间离岗智能识别监测系统基于YOLOX和RNN的深度学习算法,工作时间离岗智能识别监测系统系统利用现场已有的监控摄像机识别监控画面中的人员位置和行为特征。通过深度学习算法的处理,系统能够自动识别员工是否离岗,并计算离岗时间。一旦员工离岗时间超出预设的安全阈值,…

RADXA 5B 开启 USB OTG 网络(虚拟网卡)

RADXA 5B 开启 USB OTG 网络(虚拟网卡)按照官方文档进行配置, 会不成功 确保 USB-A 接口主板上, 插入 USB3.0 下方接口(按着主板)配置设备树 Overlays打开系统配置工具sudo rsetup依次选择 Overlays -> 警告Yes -> Manage overlays -> 空格选中Set OTG port 1 to Peri…

一架小飞机有 4 排座位,每排有 3 个座位。已经有八名乘客登机,他们在这些座位中随机就坐

问题111: 一架小飞机有 4 排座位,每排有 3 个座位。已经有八名乘客登机,他们在这些座位中随机就坐.一架小飞机有 4 排座位,每排有 3 个座位。已经有八名乘客登机,他们在这些座位中随机就坐. 接下来要登机的是一对夫妻. 问这对夫妻能够坐在同一排的 2 个相邻座位上的概率是多…

用效率驱动增长:直播团队如何协同工作?

一、企业增长离不开效率提升 在直播电商领域,企业的增长速度往往与团队运营效率息息相关。一个高效的直播团队不仅可以降低运营成本,还能快速响应市场需求,抓住增长机遇。然而,大多数团队仍在效率优化上存在不足。二、直播团队效率低下的常见问题- 1. 任务堆积:未能合理分…