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

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

时间:2025-01-20 13:43:13浏览次数:1  
标签:语句 Service 代码 Broker AWDB 1DBSample 消息 SQL SELECT

一般来说,在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 AdventureWorks2008R2
          SET 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

标签:语句,Service,代码,Broker,AWDB,1DBSample,消息,SQL,SELECT
From: https://www.cnblogs.com/luyj00436/p/18681002

相关文章

  • MySql操作指南7-数据验证与错误处理
    在使用Go语言访问MySQL数据库时,数据验证和错误处理是确保应用程序稳定性与数据完整性的核心环节。此外,日志管理对于问题追踪和系统调试具有重要作用。本文将介绍数据验证、错误处理以及日志记录与追踪的相关内容。通过这些技术,可以显著提高系统的健壮性和可维护性。 1、......
  • 【SQL精彩语句】分拆列值
    /*分拆列值原著:邹建改编:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)2007-12-16广东深圳有表tb,如下:idvalue----------------------1aa,bb2aaa,bbb,ccc欲按id,分拆value列,分拆后结果如下:idvalue-------------------1aa1bb2aaa2bbb2ccc*/--1.旧的解决方法(sql......
  • MySQL的count()方法慢
    COUNT()方法概述COUNT() 方法是MySQL中常用的聚合函数之一,用于统计满足特定条件的记录数量。虽然 COUNT()方法功能强大,但在处理大数据量时,执行速度可能会变慢。这篇文章将详细分析 COUNT()方法变慢的原因,并提供优化方案。COUNT()方法慢的原因1.表数据量大当表中记录数非......
  • MySQL里面的时间与UNIX时间戳,解决2038年问题的思考
    当前时间:NOW()当前时间:NOW()函数,传入参数是一个整数类型,传入参数可以是:空(0)、1~6;代表时间精度(秒后面的精度)。SELECTNOW(),NOW(0),NOW(1),NOW(2),NOW(3),NOW(4),NOW(5),NOW(6);如下:NOW()NOW(0)NOW(1)NOW(2)2025-01-2009:47:012025-01-2009:47:012025-01-......
  • MySQL不香吗,为啥还要Elasticsearch?
    一、先说说MySQL有啥优点MySQL这玩意,咱们都熟。行存储的代表,关系型数据库的中流砥柱。它有啥好处?老铁,太多了:数据一致性:事务支持那是杠杠的,ACID四大天王保护你数据不丢失。结构化查询:SQL语句一出,啥复杂查询都能搞定,分组、排序、子查询,随便玩。成熟稳健:发展几十年,社区大,文档多,踩......
  • 数据迁移丨借助 AI 从 PostgreSQL 到 GreatSQL
    数据迁移丨借助AI从PostgreSQL到GreatSQL本文将介绍如何从PostgreSQL到GreatSQL的数据迁移,并运用AI协助迁移更加方便。迁移的方式有很多,例如:pg_dump:导出SQL文件,修改后导入GreatSQL数据库。COPY:导出txt文本文件,导入GreatSQL数据库。pg2mysql:从PostgreSQL迁......
  • 数据库基础——mysql数据库
    一、数据库简介    数据库:数据库是一个按数据结构来存储和管理数据的计算机软件系统。简单来说,数据库是用来存放数据的。    常见数据库及端口mysql(3306):关系型数据库  mssal(1433)  oracle(1521)  db2(9500)  postgresql(5432)       ......
  • PL/SQL 删除外键 ORA-02443: 无法删除约束条件-不存在的约束条件
    在PL/SQL中删除外键,无论是在【对象】窗口可视化操作删除还是用drop语句都会报错:ORA-02443:无法删除约束条件-不存在的约束条件看到有人有同样的问题。亲测之后:情况一:常规操作ALTERTABLEtable_nameDROPCONSTRAINTforeignkeyname;情况二:需要加引号(而且是双引号)ALTERTABL......
  • Mysql--实战篇--@Transactional失效场景及避免策略(@Transactional实现原理,失效场景,内
    在Spring框架中,@Transactional注解用于声明式事务管理,能够简化事务的处理逻辑。然而,在某些情况下,@Transactional可能会失效,导致事务无法按预期工作。了解这些失效场景及其原因,可以帮助你更好地管理和调试事务问题。1、@Transactional失效的常见场景(1)、方法非public访问权......
  • 如何将MySQL数据库版本升级到5.7并确保网站正常运行?
    在云服务器上将MySQL数据库版本从较低版本升级到5.7是一项需要谨慎操作的任务,以确保网站的正常运行。以下是详细的步骤和注意事项:一、备份现有数据备份数据库:在进行任何升级操作之前,务必对现有数据库进行全面备份。可以使用命令行工具或图形界面工具(如phpMyAdmin)进行备份。......