设为首页 收藏本站
查看: 544|回复: 0

[经验分享] SQL Server 2008中Service Broker基础应用(上)

[复制链接]

尚未签到

发表于 2015-7-2 13:26:39 | 显示全部楼层 |阅读模式
  SQL Server 2008中SQL应用系列--目录索引
  导读:本文主要涉及Service Broker的基本概念及建立一个Service Broker应用程序的基本步骤。
  一、前言
  Service Broker为SQL Server提供消息队列,这提供了从数据库中发送异步事务性消息队列的方法。Service Broker消息可以保证以适当的顺序或原始的发送顺序不重复地一次性接收。并且因为内建在SQL Server中,这些消息在数据库发生故障时是可以恢复的,也可以随数据库一起备份。在SQL Server 2008中,还引入了使用Create Broker Priority命令对会话设定优先级,可以对重要的或不重要的会话进行优先级设定,以保证消息合理地处理。
  本文假定一个在线数据库BookStore中存储了一些业务订单。我们使用Service Broker应用程序将消息发送到另一个数据库BookDistribution,该数据库是分离的应用程序调用,该应用程序控制仓库入库和出库交付, 并返回消息给BookStore。
  创建Service Broker应用程序大体步骤如下:
  1、定义希望应用程序执行的异步任务。
  2、确定Service Broker的发起方服务和目标服务是否创建在同一个SQL Server实例中。如果是两个实例,实例间的通信还需要创建经过证书认证或NT安全的身份认证,并且要创建端点、路由以及对话安全模式。
  3、如果没有启用,则在多方参与的数据库中使用Alter Database命令设置Enable_broker以及Truseworthy数据库选项。
  4、为所有多方参与的数据库创建数据库主密钥。
  5、创建希望在服务之间发送的消息类型。
  6、创建契约(Contract)来定义可以由发起方发送的各种消息以及由目标发送的消息类型的种类。
  7、同时在两方参与的数据库中创建用于保存消息的队列。
  8、同时在绑定特定约定到特定队列的多方参与的数据库中创建服务。
  二、实例
  下面我们通过一个示例来实现以上步骤:
  (一)、启用数据库的Service Broker活动


-- Enabling Databases for Service Broker Activity

USE master
GO
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name ='BookStore')
CREATE DATABASE BookStore
GO
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name ='BookDistribution')
CREATE DATABASE BookDistribution
GO
ALTER DATABASE BookStore SET ENABLE_BROKER
GO
ALTER DATABASE BookStore SET TRUSTWORTHY ON
GO
ALTER DATABASE BookDistribution SET ENABLE_BROKER
GO
ALTER DATABASE BookDistribution SET TRUSTWORTHY ON  
  (二)、创建数据库主密钥


-- Creating the DatabaseMaster Key for Encryption

USE BookStore
GO
CREATE MASTER KEY
ENCRYPTION BY PASSWORD ='I5Q7w1d3'
GO
USE BookDistribution
GO
CREATE MASTER KEY
ENCRYPTION BY PASSWORD ='D1J3q5z8X6y4'
GO  
  (三)、管理消息类型
  使用CREATE MESSAGE TYPE(http://msdn.microsoft.com/en-us/library/ms187744.aspx)命令,


-- Managing Message Types

Use BookStore
GO
-- 发送图书订单的消息类型
CREATE MESSAGE TYPE [//SackConsulting/SendBookOrder]
VALIDATION = WELL_FORMED_XML
GO
--目标数据库发送的消息类型
CREATE MESSAGE TYPE [//SackConsulting/BookOrderReceived]
VALIDATION = WELL_FORMED_XML
GO
--执行同样的定义
Use BookDistribution
GO
-- 发送图书订单的消息类型
CREATE MESSAGE TYPE [//SackConsulting/SendBookOrder]
VALIDATION = WELL_FORMED_XML
GO
--目标数据库发送的消息类型
CREATE MESSAGE TYPE [//SackConsulting/BookOrderReceived]
VALIDATION = WELL_FORMED_XML
GO  
  --注意,此处没有定义消息的内容。实际的消息是消息类型的实例。
  (四)、创建契约(Contract)
  使用Create Contract(http://msdn.microsoft.com/en-us/library/ms178528.aspx)


-- Creating Contracts

Use BookStore
GO
CREATE CONTRACT
[//SackConsulting/BookOrderContract]
( [//SackConsulting/SendBookOrder]
SENT BY INITIATOR,
[//SackConsulting/BookOrderReceived]
SENT BY TARGET
)
GO
USE BookDistribution
GO
CREATE CONTRACT
[//SackConsulting/BookOrderContract]
( [//SackConsulting/SendBookOrder]
SENT BY INITIATOR,
[//SackConsulting/BookOrderReceived]
SENT BY TARGET
)
GO  
  --发起方和目标的定义必须相同
  (五)、创建队列
  队列用来保存数据。使用命令Create queue(http://msdn.microsoft.com/en-us/library/ms190495.aspx)


-- Creating Queues

Use BookStore
GO
--保存BookDistribution过来的消息
CREATE QUEUE BookStoreQueue
WITH STATUS=ON
GO
USE BookDistribution
GO
--保存BookStore过来的消息
CREATE QUEUE BookDistributionQueue
WITH STATUS=ON
GO  
  (六)、创建服务
  服务定义端点,然后使用它来将消息队列绑定到一个或多个契约上。服务使用队列和契约来定义一个或一组任务。有点拗口,是不是?
  服务是消息的发起方和接收方强制约定的规则,并将消息路由到正确的序列。
  使用Create Service(http://msdn.microsoft.com/en-us/library/ms190332.aspx)命令。


-- Creating Services

Use BookStore
GO
CREATE SERVICE [//SackConsulting/BookOrderService]
ON QUEUE dbo.BookStoreQueue--指定的队列绑定到契约
([//SackConsulting/BookOrderContract])
GO
USE BookDistribution
GO
CREATE SERVICE [//SackConsulting/BookDistributionService]
ON QUEUE dbo.BookDistributionQueue--指定的队列绑定到契约
([//SackConsulting/BookOrderContract])
GO  
  (七)、启动对话
  对话会话(dialog conservation)是在服务之间进行消息交换的操作。
  使用Begin Dialog Conversation(http://msdn.microsoft.com/en-us/library/ms187377.aspx) 命令创建新的会话。使用Send(http://msdn.microsoft.com/en-us/library/ms188407.aspx)来发送消息。使用End Conversation命令(http://msdn.microsoft.com/en-us/library/ms177521.aspx)结束会话。


-- Initiating a Dialog

Use BookStore
GO
--保存会话句柄和订单信息
DECLARE @Conv_Handler uniqueidentifier
DECLARE @OrderMsg xml;
BEGIN DIALOG CONVERSATION @Conv_Handler--创建会话
FROM SERVICE [//SackConsulting/BookOrderService]
TO SERVICE '//SackConsulting/BookDistributionService'
ON CONTRACT [//SackConsulting/BookOrderContract];
SET@OrderMsg=
'

';
SEND ON CONVERSATION @Conv_Handler--发送到BookDistribution数据库的队列中
MESSAGE TYPE [//SackConsulting/SendBookOrder]
(@OrderMsg);  
  (八)、查询队列中传入的消息


-- Querying the Queue for IncomingMessages

USE BookDistribution
GO
SELECT message_type_name, CAST(message_body as xml) message,
queuing_order, conversation_handle, conversation_group_id
FROM dbo.BookDistributionQueue   
  查询结果:
http://kdhlla.bay.livefilestore.com/y1puPBMZUdY5SiMl8bNnbfLVzhaEArlbCIPQ280kc1bZIR7Ucqh5FZuVidgU3ILR4hmdaNu76SsQrh0Mjv6jL6qhJEB4HDnN4O-/2011-4-5%2015-34-16.png?psid=1
  (九)、检索并响应消息
  使用Receive语句(http://msdn.microsoft.com/en-us/library/ms186963.aspx)从队列中读取行(消息),也可以删除已经读取的消息。Receive的结果可以填充到常规表中,也可以在局部变量中执行其他操作,或发送到其他service Broker消息。如果消息是XML数据类型的消息,则可以直接借助TSQL的XQuery来操作。


-- Receiving and Responding to aMessage

USE BookDistribution
GO
--创建一个表存放接收到的订单信息
CREATE TABLE dbo.BookOrderReceived
(BookOrderReceivedID intIDENTITY (1,1) NOT NULL,
conversation_handle uniqueidentifier NOT NULL,
conversation_group_id uniqueidentifier NOT NULL,
message_body xml NOT NULL)
GO
-- 声明变量
DECLARE @Conv_Handler uniqueidentifier
DECLARE @Conv_Group uniqueidentifier
DECLARE @OrderMsg xml
DECLARE @TextResponseMsg varchar(8000)
DECLARE @ResponseMsg xml
DECLARE @OrderID int;
--从队列中获取消息,将接收值赋于局部变量
RECEIVE TOP(1) @OrderMsg= message_body,--TOP指定最多一条消息
@Conv_Handler= conversation_handle,
@Conv_Group= conversation_group_id
FROM dbo.BookDistributionQueue;
-- 将变量值插入表中
INSERT dbo.BookOrderReceived
(conversation_handle, conversation_group_id, message_body)
VALUES
(@Conv_Handler,@Conv_Group, @OrderMsg )
-- 使用XQuery进行抽取以响应消息订单
SELECT @OrderID=@OrderMsg.value('(/order/@id)[1]', 'int' )
SELECT @TextResponseMsg=
'';
SELECT @ResponseMsg=CAST(@TextResponseMsgas xml);
-- 使用既有的会话句柄,发送响应消息到发起方
SEND ON CONVERSATION @Conv_Handler
MESSAGE TYPE [//SackConsulting/BookOrderReceived]
(@OrderMsg)
  
  (十)、结束会话


-- Ending a Conversation

USE BookStore
GO
-- 创建订单确认表
CREATETABLE dbo.BookOrderConfirmation
(BookOrderConfirmationID intIDENTITY (1,1) NOTNULL,
conversation_handle uniqueidentifierNOTNULL,
DateReceived datetimeNOTNULLDEFAULTGETDATE(),
message_body xml NOTNULL)
DECLARE @Conv_Handler uniqueidentifier
DECLARE @Conv_Group uniqueidentifier
DECLARE @OrderMsg xml
DECLARE @TextResponseMsg varchar(8000);
RECEIVE TOP(1) @Conv_Handler= conversation_handle,
@OrderMsg= message_body
FROM dbo.BookStoreQueue
INSERT dbo.BookOrderConfirmation
(conversation_handle, message_body)
VALUES (@Conv_Handler,@OrderMsg );
END CONVERSATION @Conv_Handler;
GO
USE BookDistribution
GO
DECLARE @Conv_Handleruniqueidentifier
DECLARE @Conv_Groupuniqueidentifier
DECLARE @OrderMsg xml
DECLARE @message_type_namenvarchar(256);
RECEIVE TOP(1) @Conv_Handler= conversation_handle,
@OrderMsg= message_body,
@message_type_name= message_type_name
FROM dbo.BookDistributionQueue
-- 双方必须都结束会话
IF
@message_type_name='http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @Conv_Handler;
END  
  --查询会话状态


SELECT state_desc, conversation_handle
FROM sys.conversation_endpoints   
http://kdhlla.bay.livefilestore.com/y1pJnNqAPEnEujLP2hWUO138lQKEzOaPm6ptS5MYjmXx3YA-r2bdGH6HElWICGVswX5gy1ocjmzo7wa2Uec5eVwaK9G8zVRhbfG/2011-4-5%2016-07-38.png?psid=1
  三、小结
  本文通过一个实例演示了一个用来发送图书订单消息分发控制数据库的简单的消息交换应用程序。发起方发送图书订单,发回一个响应,并在两个数据库上使用END Conservation结束会话。现实场景中可以转换为其他消息类型、契约、服务和队列。合理运用Service Broker应用程序的异步特性可以防止因应用程序挂起而导致业务系统产生瓶颈。
  本文参考:
  1、SQL Server 2005 Service Broker 初探
  http://msdn.microsoft.com/zh-cn/library/ms345108%28v=sql.90%29.aspx
  2、SQL Server 2008 Transact-SQL Recipes: A Problem-Solution Approach
  http://www.amazon.com/Server-2008-Transact-SQL-Recipes-Problem-Solution/dp/1590599802

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-82551-1-1.html 上篇帖子: 操作SQL Server Mobile数据库的常用C#代码 下篇帖子: 创建集成含有SQL Server 2008 RTM + Service Pack 1 的安装 (翻译)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表