热点链接

天龙高手心水180000

主页 > 天龙高手心水180000 >
49码出特公式 '
时间: 2019-06-03
c?SQL Server 2008中Service Broker基础应用(上)_知识库_博客园
导读:本文主要涉及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 ActivityUSE masterGOIF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'BookStore')CREATE DATABASE BookStoreGOIF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'BookDistribution')CREATE DATABASE BookDistributionGOALTER DATABASE BookStore SET ENABLE_BROKERGOALTER DATABASE BookStore SET TRUSTWORTHY ONGOALTER DATABASE BookDistribution SET ENABLE_BROKERGOALTER DATABASE BookDistribution SET TRUSTWORTHY ON  (二)、创建数据库主密钥-- Creating the DatabaseMaster Key for EncryptionUSE BookStoreGOCREATE MASTER KEYENCRYPTION BY PASSWORD = 'I5Q7w1d3'GOUSE BookDistributionGOCREATE MASTER KEYENCRYPTION BY PASSWORD = 'D1J3q5z8X6y4'GO  (三)、治理消息类型   使用CREATE MESSAGE TYPE(http://msdn.microsoft.com/en-us/library/ms187744.aspx)命令,-- Managing Message TypesUse BookStoreGO-- 发送图书订单的消息类型CREATE MESSAGE TYPE [//SackConsulting/SendBookOrder]VALIDATION = WELL_FORMED_XMLGO--目标数据库发送的消息类型CREATE MESSAGE TYPE [//SackConsulting/BookOrderReceived]VALIDATION = WELL_FORMED_XMLGO--执行同样的定义Use BookDistributionGO-- 发送图书订单的消息类型CREATE MESSAGE TYPE [//SackConsulting/SendBookOrder]VALIDATION = WELL_FORMED_XMLGO--目标数据库发送的消息类型CREATE MESSAGE TYPE [//SackConsulting/BookOrderReceived]VALIDATION = WELL_FORMED_XMLGO   --注意,此处没有定义消息的内容。实际的消息是消息类型的实例。  (四)、创建契约(Contract)   使用Create Contract(http://msdn.microsoft.com/en-us/library/ms178528.aspx)-- Creating ContractsUse BookStoreGOCREATE CONTRACT[//SackConsulting/BookOrderContract]( [//SackConsulting/SendBookOrder]SENT BY INITIATOR,[//SackConsulting/BookOrderReceived]SENT BY TARGET)GOUSE BookDistributionGOCREATE 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 QueuesUse BookStoreGO--保存BookDistribution过来的消息CREATE QUEUE BookStoreQueueWITH STATUS=ONGOUSE BookDistributionGO--保存BookStore过来的消息CREATE QUEUE BookDistributionQueueWITH STATUS=ONGO  (六)、创建服务  服务定义端点,然后使用它来将消息队列绑定到一个或多个契约上。服务使用队列和契约来定义一个或一组任务。有点拗口,是不是?  服务是消息的发起方和接收方强制约定的规则,并将消息路由到正确的序列。  使用Create Service(http://msdn.microsoft.com/en-us/library/ms190332.aspx)命令。-- Creating ServicesUse BookStoreGOCREATE SERVICE [//SackConsulting/BookOrderService]ON QUEUE dbo.BookStoreQueue--指定的队列绑定到契约([//SackConsulting/BookOrderContract])GOUSE BookDistributionGOCREATE 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 DialogUse BookStoreGO--保存会话句柄和订单信息DECLARE @Conv_Handler uniqueidentifierDECLARE @OrderMsg xml;BEGIN DIALOG CONVERSATION @Conv_Handler--创建会话FROM SERVICE [//SackConsulting/BookOrderService]TO SERVICE '//SackConsulting/BookDistributionService'ON CONTRACT [//SackConsulting/BookOrderContract];SET @OrderMsg ='<order id="3439" customer="22" orderdate="2/15/2011"><LineItem ItemNumber="1" ISBN="1-59059-592-0" Quantity="1" /></order>';SEND ON CONVERSATION @Conv_Handler--发送到BookDistribution数据库的队列中MESSAGE TYPE [//SackConsulting/SendBookOrder](@OrderMsg);  (八)、查询队列中传入的消息 -- Querying the Queue for IncomingMessagesUSE BookDistributionGOSELECT message_type_name, CAST(message_body as xml) message,queuing_order, conversation_handle, conversation_group_idFROM dbo.BookDistributionQueue   查询结果:   (九)、检索并响应消息   使用Receive语句(http://msdn.microsoft.com/en-us/library/ms186963.aspx)从队列中读取行(消息),也可以删除已经读取的消息。Receive的结果可以填充到常规表中,也可以在局部变量中执行其他操作,或发送到其他service Broker消息。如果消息是XML数据类型的消息,则可以直接借助TSQL的XQuery来操作。-- Receiving and Responding to aMessageUSE BookDistributionGO--创建一个表存放接收到的订单信息CREATE TABLE dbo.BookOrderReceived(BookOrderReceivedID int IDENTITY (1,1) NOT NULL,conversation_handle uniqueidentifier NOT NULL,conversation_group_id uniqueidentifier NOT NULL,message_body xml NOT NULL)GO-- 声明变量DECLARE @Conv_Handler uniqueidentifierDECLARE @Conv_Group uniqueidentifierDECLARE @OrderMsg xmlDECLARE @TextResponseMsg varchar(8000)DECLARE @ResponseMsg xmlDECLARE @OrderID int;--从队列中获取消息,将接收值赋于局部变量RECEIVE TOP(1) @OrderMsg = message_body,--TOP指定最多一条消息@Conv_Handler = conversation_handle,@Conv_Group = conversation_group_idFROM 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 ='<orderreceived id= "' +CAST(@OrderID as varchar(10)) +'"/>';SELECT @ResponseMsg = CAST(@TextResponseMsg as xml);-- 使用既有的会话句柄,发送响应消息到发起方SEND ON CONVERSATION @Conv_HandlerMESSAGE TYPE [//SackConsulting/BookOrderReceived]   (十)、结束会话 -- Ending a ConversationUSE BookStoreGO-- 创建订单确认表CREATE TABLE dbo.BookOrderConfirmation(BookOrderConfirmationID int IDENTITY (1,1) NOT NULL,全年图库资料,conversation_handle uniqueidentifier NOT NULL,DateReceived datetime NOT NULL DEFAULT GETDATE(),message_body xml NOT NULL)DECLARE @Conv_Handler uniqueidentifierDECLARE @Conv_Group uniqueidentifierDECLARE @OrderMsg xmlDECLARE @TextResponseMsg varchar(8000);RECEIVE TOP(1) @Conv_Handler = conversation_handle,@OrderMsg = message_bodyFROM dbo.BookStoreQueueINSERT dbo.BookOrderConfirmation(conversation_handle, message_body)VALUES (@Conv_Handler,@OrderMsg );END CONVERSATION @Conv_Handler;GOUSE BookDistributionGODECLARE @Conv_Handler uniqueidentifierDECLARE @Conv_Group uniqueidentifierDECLARE @OrderMsg xmlDECLARE @message_type_name nvarchar(256);RECEIVE TOP(1) @Conv_Handler = conversation_handle,@OrderMsg = message_body,@message_type_name = message_type_nameFROM dbo.BookDistributionQueue-- 双方必须都结束会话IF@message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'BEGINEND CONVERSATION @Conv_Handler;END   --查询会话状态SELECT state_desc, conversation_handleFROM sys.conversation_endpoints   三、小结   本文通过一个实例演示了一个用来发送图书订单消息分发控制数据库的简单的消息交换应用程序。发起方发送图书订单,发回一个响应,并在两个数据库上使用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/1590599802Service Broker

Copyright 2017-2023 http://www.niutu98.com All Rights Reserved.