概述  

SQL Server Service Broker
用来创设用于沟通新闻的对话。音信在指标和发起方这七个端点之间开始展览调换。音讯用于传输数据和接触新闻收到时的管理进度。目的和发起方既可以够在一如既往数据库引擎实例的一样数据库或不一致数据库中,也得以在分歧数据库引擎实例的一样数据库或区别数据库中。

 

各样 瑟维斯 Broker
会话都有五个端点:会话发起方和指标。您将实践下列任务:

  • 为指标创造多少个劳务和队列,并为发起方创立多个劳动和队列。
  • 创造央求音讯类型和回应音信类型。
  • 创设约定,钦定央求消息从发起方传递到指标並且答复音讯从指标传递到发起方。

下一场推行三个总结会话:

  • 运营会话。
  • 从发起方向指标发送二个伸手。
  • 在对象处接到诉求并将回应发送到发起方。
  • 在发起方处接收答复。
  • 终止会话。

对于其两端在同一 数据库引擎
实例中的会话,其新闻不通过互连网传输。数据库引擎
安全性和权杖将限制对授权主体的探访。此方案不供给网络加密。

一、创立会话对象

1.启用Service Broker

----创建数据库
IF NOT EXISTS(SELECT * FROM SYS.DATABASES WHERE name='Dsend')
BEGIN
     CREATE DATABASE Dsend;

END

USE master;
GO
---开启数据库BROKER
ALTER DATABASE Dsend  SET ENABLE_BROKER;
GO

SELECT is_broker_enabled FROM SYS.DATABASES WHERE NAME='Dsend'

USE Dsend;
GO

2.创制音信类型

由于平常在七个数据库引擎实例间引用 Service Broker 对象,由此大比较多Service Broker 对象的名号都以 U福特ExplorerI
格式的。那促进确定保障它们在多台计算机上是头一无二的。那三种新闻类型都钦定Service Broker 将只验证音信是不是是格式准确的 XML 文档,并且钦点 ServiceBroker 将不遵照一定框架结构验证 XML。

CREATE MESSAGE TYPE
       [//Dsend/test/RequestMessage]
       VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
       [//Dsend/test/ReplyMessage]
       VALIDATION = WELL_FORMED_XML;

创设诉求音信和答复音讯,何况音讯的格式为XML格式。

留神:Service Broker
验证传入消息。假若消息包蕴的新闻正文与钦赐的求证类型不符,则 ServiceBroker
将舍弃此无效音讯,并向发送此新闻的服务再次来到一条错误消息。会话双方必须定义同样的音讯类型名称。为方便排除故障,尽管Service Broker
不需要会话两方动用一样的印证,但常见会话双方照旧会为消息类型钦命同样的表明。新闻类型不能够是这段日子对象。允许利用以
# 伊始的新闻类型名称,但它们是永久对象。

3.创立约定

预定用于定义在 Service Broker
会话中所使用的音信类型,还用于显著会话的哪一端能够发送该项指标音信。每一个会话都要依据贰个预订。当会话开头时,运行服务为会话钦赐约定。目的服务钦赐该对象服务将接受其对话的预定。 

/*
SENT BY INITIATOR    ----指示只有会话的发起方才能发送指定消息类型的消息。启动会话的服务称为会话的“发起方”
SENT BY TARGET       ----指示只有会话的目标才能发送指定消息类型的消息。接受由另一个服务启动的会话的服务称为会话的目标。
SENT BY ANY          ----指示发起方和目标都可以发送此类型的消息。
*/

CREATE CONTRACT [//Dsend/test/RequestContract]
      ([//Dsend/test/RequestMessage]    
       SENT BY INITIATOR,             ---约定只有发起方才能使用//Dsend/test/RequestMessage消息类型
       [//Dsend/test/ReplyMessage]
       SENT BY TARGET                 ---约定只有答复方才能使用//Dsend/test/ReplyMessage消息类型
      );

4.创设队列

SQL Server Servicewww.yabovip4.com Broker成立单个数据库会话(音信队列)。队列能够积累音讯。当一条针对某项服务的消息达到时,Service Broker
会将该消息归入与该服务涉及的队列中。

创设发起方和答复方的行列。

CREATE QUEUE RequestQueue WITH STATUS=ON;
CREATE QUEUE ReplyQueue WITH STATUS=ON;

注意:

1.队列能够由此SELECT 语句询问,但是不可能应用INSERT、UPDATE、DELETE 或
TRUNCATE 语句来操作。只好动用在 Service Broker 会话中运作的讲话(如
SEND、RECEIVE 和 END CONVERubiconSATION)来修改队列的剧情。

2.队列也许不是暂且对象。由此,以 # 早先的队列名称无效。

3.因而以不可用状态成立队列,能够先准备好服务的基础结构,然后再允许在队列中抽取音讯。

4.比方队列中向来不音信,则 Service Broker
不会终止激活存款和储蓄进程。纵然队列中在长时间内并未有可用消息,应退出激活存储进程。

5.在 Service Broker
运营存款和储蓄进程时将检查激活存款和储蓄进程的权能,并非在创立队列时检查。CREATE
QUEUE 语句不表达 EXECUTE AS 子句中钦命的用户是还是不是有权力奉行 PROCEDURE
NAME 子句中钦定的存放进度。

6.队列不可用时,Service Broker
将要数据库的传输队列中保留使用该队列的服务的消息。sys.transmission_queue
目录视图提供传输队列的视图。

 

例:创制具有四个参数的行列

以下示例在 DEFAULTSQL Server Servicewww.yabovip4.com Broker成立单个数据库会话(音信队列)。
文件组中创制三个行列。该队列不可用。新闻被保存在队列中,直到新闻所属的对话甘休。通过
ALTE索罗德 QUEUE 启用队列后,该队列将运维存款和储蓄进度
2008R2.dbo.expense_procedure 来管理音信。此存款和储蓄进程以运维
CREATE QUEUE 语句的用户的身份执行。该队列最多运转存储进度的 10
个实例。

CREATE QUEUE ExpenseQueue
    WITH STATUS = OFF,
      RETENTION = ON,
      ACTIVATION (
          PROCEDURE_NAME = AdventureWorks2008R2.dbo.expense_procedure,
          MAX_QUEUE_READERS = 10,
          EXECUTE AS SELF )
    ON [DEFAULT] ;

SQL Server Servicewww.yabovip4.com Broker成立单个数据库会话(音信队列)。5.创办服务

Service Broker
使用劳务的名称路由信息、将新闻传递到数据库中的正确队列,以及强制实践会话的约定。贰个劳动能够同期绑定多少个约束。

--1.创建要用于发起方的队列和服务。由于未指定约定名称,因而其他服务不可将此服务用作目标服务,此服务只能启动会话。
CREATE SERVICE
       [//Dsend/test/RequestService]
       ON QUEUE RequestQueue     
GO
---2.创建接答复服务
CREATE SERVICE
       [//Dsend/test/ReplyService]
       ON QUEUE ReplyQueue
       ([//Dsend/test/RequestContract]
       )
       ;
GO

SQL Server Servicewww.yabovip4.com Broker成立单个数据库会话(音信队列)。SQL Server Servicewww.yabovip4.com Broker成立单个数据库会话(音信队列)。留意:服务公开与其涉及的约定提供的意义,以便别的服务可选用该成效。CREATE
SE库罗德VICE
语句钦点针对此服务的预订。三个劳动只可以是采用该服务内定的预订会话的指标。未钦点约定的服务不会向其余服务公开任何意义。

从此以后服务运转的对话可利用其余约定。假诺服务仅运转会话,则创建服务时可不点名约定。ServiceBroker 从远程服务承受新会话时,指标服务的名目决定了 Broker
在对话中纳入消息的连串。

 

例:创立具有八个约定的劳动

CREATE SERVICE [//Adventure-Works.com/Expenses] ON QUEUE ExpenseQueue
    ([//Adventure-Works.com/Expenses/ExpenseSubmission],
     [//Adventure-Works.com/Expenses/ExpenseProcessing]) ;

5.开启回话

DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
DECLARE @RequestMsg NVARCHAR(100);

BEGIN TRANSACTION;

BEGIN DIALOG @InitDlgHandle
     FROM SERVICE
      [//Dsend/test/RequestService] ---指定的服务是用于答复消息的返回地址
     TO SERVICE
      N'//Dsend/test/ReplyService'  ---指定的服务是消息发送到的地址。
     ON CONTRACT
      [//Dsend/test/RequestContract]
     WITH
         ENCRYPTION = OFF;

SELECT @InitDlgHandle;

SELECT @RequestMsg =
       N'<RequestMsg>3</RequestMsg>';

SEND ON CONVERSATION @InitDlgHandle
     MESSAGE TYPE 
     [//Dsend/test/RequestMessage]
     (@RequestMsg);

SELECT @RequestMsg AS SentRequestMsg;

COMMIT TRANSACTION;
GO

 

6.接收方接收音讯并重回消息给发送方

DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsg NVARCHAR(100);
DECLARE @RecvReqMsgName sysname;
DECLARE @Message NVARCHAR(100)

BEGIN TRANSACTION;

WAITFOR
( RECEIVE TOP(1)
    @RecvReqDlgHandle = conversation_handle,
    @RecvReqMsg = message_body,
    @RecvReqMsgName = message_type_name
  FROM ReplyQueue
), TIMEOUT 1000;

SELECT @RecvReqMsg AS ReceivedRequestMsg;
SELECT @RecvReqMsgName;


BEGIN

     -----返回接收消息确认结果到发起方

     DECLARE @ReplyMsg NVARCHAR(100);
     SELECT @ReplyMsg =
     N'<ReplyMsg>Reply Message</ReplyMsg>';

     SEND ON CONVERSATION @RecvReqDlgHandle
          MESSAGE TYPE 
          [//Dsend/test/ReplyMessage]
          (@ReplyMsg);

     SELECT @RecvReqDlgHandle;

     ---正常的流程不是在这里结束会话
     END CONVERSATION @RecvReqDlgHandle;
END

IF @RecvReqMsgName =N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
    BEGIN
         END CONVERSATION @RecvReqDlgHandle;
    END

COMMIT TRANSACTION;
GO

例:接收数据同一时间插入表变量

www.yabovip4.com 1www.yabovip4.com 2

DECLARE @conversation_group_id UNIQUEIDENTIFIER ;

DECLARE @procTable TABLE(
     service_instance_id UNIQUEIDENTIFIER,
     handle UNIQUEIDENTIFIER,
     message_sequence_number BIGINT,
     service_name NVARCHAR(512),
     service_contract_name NVARCHAR(256),
     message_type_name NVARCHAR(256),
     validation NCHAR,
     message_body VARBINARY(MAX)) ;

SET @conversation_group_id = <retrieve conversation group ID from database> ;

RECEIVE TOP (1)
    conversation_group_id,
    conversation_handle,
    message_sequence_number,
    service_name,
    service_contract_name,
    message_type_name,
    validation,
    message_body
FROM ExpenseQueue
INTO @procTable
WHERE conversation_group_id = @conversation_group_id ;

View Code

 

7.发送方收到新闻终止会话

DECLARE @RecvReplyMsg NVARCHAR(100);
DECLARE @RecvReplyDlgHandle UNIQUEIDENTIFIER;
DECLARE @RecvReqMsgName sysname;

BEGIN TRANSACTION;

WAITFOR
( RECEIVE TOP(1)
    @RecvReplyDlgHandle = conversation_handle,
    @RecvReplyMsg = message_body,
    @RecvReqMsgName=message_type_name
  FROM RequestQueue
), TIMEOUT 1000;

IF @RecvReqMsgName =N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
    BEGIN
         END CONVERSATION @RecvReqDlgHandle;
    END

SELECT @RecvReplyMsg AS ReceivedReplyMsg;

COMMIT TRANSACTION;

GO

三、查询

SELECT state_desc,*
FROM sys.conversation_endpoints

SELECT message_type_name, CAST(message_body as xml) message,*
FROM dbo.RequestQueue

SELECT message_type_name, CAST(message_body as xml) message,*
FROM dbo.ReplyQueue

SELECT CAST(message_body as xml) message,* FROM sys.transmission_queue

--END CONVERSATION '236AF2C5-57F4-E711-A9E6-005056C00008';

四、删除会话对象

IF EXISTS (SELECT * FROM sys.services
           WHERE name =
           N'//AWDB/1DBSample/TargetService')
     DROP SERVICE
     [//AWDB/1DBSample/TargetService];

IF EXISTS (SELECT * FROM sys.service_queues
           WHERE name = N'TargetQueue1DB')
     DROP QUEUE TargetQueue1DB;

-- Drop the intitator queue and service if they already exist.
IF EXISTS (SELECT * FROM sys.services
           WHERE name =
           N'//AWDB/1DBSample/InitiatorService')
     DROP SERVICE
     [//AWDB/1DBSample/InitiatorService];

IF EXISTS (SELECT * FROM sys.service_queues
           WHERE name = N'InitiatorQueue1DB')
     DROP QUEUE InitiatorQueue1DB;

IF EXISTS (SELECT * FROM sys.service_contracts
           WHERE name =
           N'//AWDB/1DBSample/SampleContract')
     DROP CONTRACT
     [//AWDB/1DBSample/SampleContract];

IF EXISTS (SELECT * FROM sys.service_message_types
           WHERE name =
           N'//AWDB/1DBSample/RequestMessage')
     DROP MESSAGE TYPE
     [//AWDB/1DBSample/RequestMessage];

IF EXISTS (SELECT * FROM sys.service_message_types
           WHERE name =
           N'//AWDB/1DBSample/ReplyMessage')
     DROP MESSAGE TYPE
     [//AWDB/1DBSample/ReplyMessage];
GO

 

参考:http://www.cnblogs.com/downmoon/archive/2011/04/05/2005900.html

参考:

总结

应用单数据库会话可以拍卖一般的行列发送和读写信息的情景,在那之中sys.conversation_endpoints系统视图须要重点关心。

 

 

 

 

 

备注:

    作者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接,否则保留追究责任的权利。

《欢迎交流讨论》

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注