Service Broker学习(一)

0.参考文献:

SQL Server Service Broker MSDN文档总览

SQL Server 2005 Service Broker 初探

Servic Broker对话会话

1.Service Broker 编程

Service Broker 功能通过 SQL Server 中的新对象启用,这些新对象可以由一组 T-SQL 扩展来创建和操作。为了数据库程序员的方便,使用了他们熟悉的用于配置其他数据库对象的 CREATE、ALTER 和 DROP DDL 语句来配置 Service Broker 应用程序。用于创建 Service Broker 对话以及在对话中发送和接收消息的命令是 Transact SQL 语言的 DML 扩展。接收命令的语法与选择命令相似,它返回包含消息的行集,就像选择命令返回包含行的行集一样。熟悉 Transact SQL 编程的开发人员会发现学习 Service Broker 编程非常容易。用于为 Service Broker 编程的客户端 API 与用于为所有数据库编程的 API 相同,例如 OLEDB、ODBC、ADO、ADO.NET 等等。下面是 Service Broker 使用的对象。

1.1.队列(QUEUE)

Service Broker 使用队列在消息发送程序和消息接收程序之间提供松散耦合。发送程序可以使用 SEND 命令将消息放到队列中,然后应用程序继续操作(不用等待接受程序发送确认回复)并依靠 Service Broker 来确保消息到达其目标位置。

队列允许较大的计划灵活性。例如,发送程序可以发送多条消息以供多个接收程序并行处理。接收程序可能在消息发送很长时间后才处理消息,但由于传入消息进行了排队,因此接收程序可以按其自己的速率处理消息,而且发送程序无须等待接收程序完成处理便可继续操作

1.2.对话(DIALOG)

Service Broker 还实现了对话,对话是两个端点之间的双向消息流。对话中的所有消息都进行了排序,而且对话消息总是按照发送的顺序传送。该顺序在事务、输入线程、输出线程以及系统崩溃和重新启动过程中都保持不变。

对话是一种会话类型。Service Broker 会话是持久可靠的通信通道。在以后的 SQL Server 版本中,Service Broker 将包括一对多的单向会话,也称为可靠的“发布-订阅”。在 SQL Server 2005 中,对话是唯一的会话类型,因此这两个术语同义。

每条消息都包括唯一标识与它相关的对话的会话句柄。例如,某个订单输入应用程序可能同时使用发货应用程序、库存应用程序和帐单应用程序打开了对话。因为每个应用程序中的消息都具有唯一的会话句柄,所以可以轻松地确定发送每条消息的应用程序。

下面的关系图显示对话的消息流:

1.3.消息类型(MESSAGE TYPE)

当前,所有 Service Broker 消息都与特定的消息类型相关联。消息类型是与消息一起传送的标签,因此接收消息的应用程序可以确定所接收消息的类型。此外,如果消息包含 XML 文档,则消息类型可以与 XML 架构集合相关联。如果为某个消息类型指定了架构集合,则所接收的该类型消息将在收到时根据架构集合进行验证,而没有通过架构验证的消息将会被拒绝。

1.4.规范(CONTRACT)

Service Broker 规范是一个消息类型集合。一个对话总是与一个规范相关联,而规范定义哪些消息类型可以通过对话发送。

1.5.服务(SERVICE)

Service Broker 服务将一个或多个规范与一个队列相关联。规范定义可以将哪些消息类型发送到队列。服务名称用于建立对话的端点。服务名称用作实际队列的别名,因此您可以编写引用服务名称的 Service Broker 程序,然后在部署应用程序时将它与实际队列相关联。

2.Service Broker“Hello World”

大多数编程语言书籍都以“Hello World”示例开始,因此我们也在 Service Broker 中使用 Hello World 作为示例。为简化示例,我使用可以从 SQL Server Management Studio 查询窗口运行的 T-SQL 进行编写。大多数 Service Broker 应用程序将作为普通的数据库应用程序,这些应用程序由通过 ADO 或 ADO.NET 与数据库进行通信的可执行程序和使用 T-SQL 或 .NET 语言编写的 SQL Server 存储过程构成。

要发送和接收消息,必须首先创建向 Service Broker 描述应用程序的消息传送部分的元数据对象。在 SQL Server 2005 中,使用新添加的 DDL 语句来创建、修改和删除 Service Broker 元数据。

代码示例

View Code
-- step1
-- 创建要使用的数据库
Create Database HelloWorldDB
go

Use HelloWorldDB
go

--step2
/*创建要使用的两种消息类型。我们要使用的消息将是
  字符串而不是 XML,因此无需进行验证 
*/
CREATE MESSAGE TYPE [HelloWorldRequest] VALIDATION = NONE 
CREATE MESSAGE TYPE [HelloWorldResponse] VALIDATION = NONE 

--step3:
/*创建一个限制此对话框中消息类型的规范。
  请求由对话框的初始化程序发出响应消息由对话框目标发送。
*/
CREATE CONTRACT [HelloWorldContract]
( 
    [HelloWorldRequest] SENT BY initiator,
    [HelloWorldResponse] SENT BY target
)

--step4
-- 创建对话框在其间通信的两个队列。A对话框请求两个队列。
CREATE QUEUE [HelloWorldTargetQueue]
CREATE QUEUE [HelloWorldInitiatorQueue]

--step5
-- 创建命名对话框端点的服务。服务会将会话端点连接到队列。
CREATE SERVICE [HelloWorldRequestService] ON QUEUE [HelloWorldTargetQueue]
( 
    [HelloWorldContract] 
)
CREATE SERVICE [HelloWorldResponseService] ON QUEUE [HelloWorldInitiatorQueue]
go

--step6
/*现在已经设置了元数据,可以发送消息了。请注意,由于初始化程序和目标服务
  位于同一 SQL Server 实例中,因此消息将直接转到目标队列而不会通过传送队
  列传送。由于 Service Broker 内置在数据库中,因此可以进行此项性能优化。
*/
SET NOCOUNT ON
DECLARE @conversationHandle uniqueidentifier
Begin Transaction--事物开始
-- 开始 Hello World 服务的对话
BEGIN DIALOG  @conversationHandle
FROM SERVICE    [HelloWorldResponseService]
TO SERVICE      'HelloWorldRequestService'
ON CONTRACT     [HelloWorldContract]
WITH ENCRYPTION = OFF, LIFETIME = 600;
-- 发送消息
SEND ON CONVERSATION @conversationHandle 
MESSAGE TYPE [HelloWorldRequest] (N'Hello World')
commit--事物提交

--step7
--让我们查看目标队列以确保成功发送了消息。检查目标队列以确认消息已送达
select * from [HelloWorldTargetQueue]
go
-- 将消息主体转换为字符串,以便我们查看其中包含的内容
select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue]
go

--step8
/*现在可以从目标队列中接收消息并将响应发送回初始化程序。使用 Receive 命令可从队列接收消息
*/
-- 声明变量以存储接收到的数据
SET NOCOUNT ON
DECLARE @conversationHandle uniqueidentifier --对话的标识符 
declare @message_body nvarchar(MAX)--消息体
declare @message_type_name sysname;--消息类型名称

-- Service Broker 命令总是位于事务中
Begin Transaction;

-- Receive 命令的格式类似于一个选择列表。首先列出要获取的列,
-- 然后指定要从中获取消息的队列
RECEIVE top(1) -- 只接收一条消息,因此我们可以直接保存到变量中。
@message_type_name=message_type_name,  -- 接收的消息类型
@conversationHandle=conversation_handle, -- 对话的标识符,我们通过下列语句接收该消息
@message_body=message_body  -- 作为varbinary(MAX) blob 的消息内容
FROM [HelloWorldTargetQueue]

print @message_body

-- 如果这是一条 hello world 消息,则用相应的问候语回答
if @message_type_name = N'HelloWorldRequest'
Begin
SEND ON CONVERSATION @conversationHandle 
MESSAGE TYPE [HelloWorldResponse] 
(N'Hello From '+@@servername )

-- 这是我们希望从初始化程序接收的唯一消息,因此现在可以安全地结束对话。
END CONVERSATION @conversationHandle
End
-- 提交事务
-- 如果此时我们回滚,所有内容将退回到
-- 我们开始时的状态 – 消息会返回到队列,并且没有发送响应
Commit
go

--step9
-- 确认我们从队列中删除了消息
select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue]
go

--step10
--响应已在对话中发送回初始化程序队列,现在检查响应是否成功到达:
select cast(message_body as nvarchar(MAX)) from [HelloWorldInitiatorQueue]
go

--step11
-- 最后接收并显示响应消息:
RECEIVE  
cast(message_body as nvarchar(MAX))
FROM [HelloWorldInitiatorQueue]

执行上述代码以后,我们可以查看SSMS中HelloWorldDB的Servic Broker属性,如下图所示,主要列出了我们创建的队列、服务等信息:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server 2005 的一个主要成就是可以实现可靠、可扩展且功能完善的数据库应用程序。与 .NET Framework 2.0 公共语言运行库 (CLR) 的集成使开发人员可以将重要的业务逻辑与存储过程合并,而 T-SQL 和 XML 中的新增功能扩展了数据操作的可用范围以及开发人员可用的存储功能。另一个重要功能是 SQL Server Service Broker,它为数据库应用程序增加了可靠、可扩展、分布式异步功能。 为什么要编写异步排队操作? 在开发 SQL Server 2005 时,我们与成功开发过大型可扩展数据库应用程序的人员进行了交谈。结果发现他们几乎所有的应用程序中都有一个或多个操作是以异步排队方式执行的。股票交易系统中的结算活动是排队的,这样可以在后台进行结算,在前端处理其他交易。订单输入系统中的发货信息放在一个排队中,稍后将由另一台服务器(通常位于其他位置)上运行的发货系统读取。旅行预订系统在客户填写完路线后再进行实际的预订,并在预订完成后发送确认电子邮件。在所有这些示例中,许多工作都是通过异步方式完成的,从而提高了系统的响应速度,因此用户无须等待工作完成就可以收到响应。 在大多数大型系统中,经过仔细分析后都可以发现,许多处理都可以通过异步方式完成。虽然应用程序中的排队任务无须立即完成,但系统必须确保这些任务能够可靠地完成。Service Broker 使异步排队任务的执行可靠并且易于实现。 使应用程序中的部分任务异步执行的另一个优势是这些任务的处理工作可以在资源可用时完成。如果订单输入系统中的发货任务可以从队列中执行,发货系统就无需具有处理峰值订单负载的能力。在许多订单输入系统中,峰值订单率可能是平均订单率的两倍或三倍。由于订单输入系统必须具有处理峰值负载的能力,因此大量处理能力在很大一部分时间内都处于闲置状态。如果在出现峰值时对异步任务进行排队并在空闲时执行,将显著提高系统的利用率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值