SQLServer -ServiceBroker

1.ServiceBroker简介

直接把文档原话copy过来吧:

SQL Service Broker is one of the best recent features in SQL Server 2005 because it makes it

possible to write queuing and message-based applications. With Service Broker, database

developers can write asynchronous applications to communicate between databases or servers and

can easily build distributed, secure, and reliable applications.

简单来说,Service Broker就是个消息队列,并且可以用来写分布式的异步的应用程序。

 

2.ServiceBroker的结构:

Service Broker的建立还是有点复杂的,说具体情况前:

先说下Service Broker基本构成:message type,

然后是根据message type创建的contracts,

接着是queue,

最后是基于queue和contracts建立的service,

以上的message type,contract,queue,还有service是service broker的基本构成。

另外servicebroker是可以在同一个sqlserver实例上两个数据库间进行,也可以在两个sqlserver实例间进行(当然这个的配置会比

前者麻烦的多,但也只有这种的模式才更有意义),所以实现servicebroker至少需要两个数据库,一个发起数据库,一个目标数据库。

 

3.ServiceBroker的创立

在创立之前,先要执行以下脚本修改数据库的TRUSTWORTHY属性, 

如果不是在两个sqlserver实例间,而只是在同一sqlserver实例中的两个数据库间使用servicebroker就需要打开这个属性。

如果是两个sqlserver实例间,因为会使用transport的安全(这个跟看的书讲的有点差别,书上说的可以不开启这个属性的情况

只有在使用证书安全并启了会话加密的情况才不需要设置这个属性)就不需要开启这个属性了。 

另外还有检查当前数据库是不是开启了servicebroker功能,这个功能默认可能是关闭的,如果是关闭的,可以在要使用的数据库

的属性窗口的选项页中,开启这个功能。

修改trustworth设置和检查servicebroker是否开启的脚本:

/*If you are using certificate security with dialog encryption ON (explained later in

the chapter), then setting the TRUSTWORTHY bit to ON is not necessary.

在两个sqlserver实例间进行servicebroker,也不需要将其设置为on,即使endpoint的验证使用的是windows模式*/

ALTER DATABASE dbname SET TRUSTWORTHY ON
GO
use initialDB
GO


/*如果is_broker_enabled没有开启,则需要在数据库属性中打开,否则

无法使用servicebroker*/

select service_broker_guid,is_broker_enabled,is_trustworthy_on

from sys.databases where database_id=DB_ID()

go

 

创建message type的脚本,这里建立了三个message type(比较懒,就没创立xml类型的消息,只建立了个任意类型的消息,另外

消息类型名起的也不标准,准确具体的参见sql的联机丛书吧,下面的各命令也都一样,具体的参见sql联机帮助吧):

create message type mtesttype

validation=none

go

create message type mtesttype1

validation=none

go

create message type mtesttype2

validation=none

go

 

创建合同contract,这里是根据上面创建的三个消息类型,定义mtesttype只能被初始数据库发送,type1只能由目标数据库发出,

type2可以被任意(也就是初始和目标)数据库发送。

create contract mtestcontract
(
mtesttype sent by initiator,
mtesttype1 sent by target,
mtesttype2 sent by any
)


下面是创建一个在数据库收到消息的时候自动执行的存储过程,这个存储过程将用在创建队列的时候使用,因为这个存储过程是建立在发起数据库上的,所以在这个存储过程里只接收了消息,并对消息的类型进行了判断,然后根据消息类型执行结束会话或者将从目标数据库发来的消息插入一张表中。
create proc processmsg
as
declare 
@msgtype varchar(255),
@msgbody varchar(255),
@cid uniqueidentifier
begin try
begin tran
waitfor(
/*You can also specify a WHERE clause in the RECEIVE statement, but it is not a full-featured WHERE
clause. You can only specify a conversation_handle or conversation_group_id.*/
receive top(1)
@msgtype=message_type_name,
@msgbody=case when validation='N'
then cast(message_body as varchar(255))
end,
@cid=conversation_handle
from dbo.testqueue),timeout 3000
if(@@ROWCOUNT = 0 or @@ERROR <> 0)
begin
rollback tran
goto done
end
else
begin
if @msgtype = 'mtesttype1'
begin
insert into t2(msg,cid,mtype) values(@msgbody,@cid,@msgtype)
end
if @msgtype = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
begin
end conversation @cid
end
end
commit tran
end try
begin catch
while(@@TRANCOUNT > 0) rollback tran
select ERROR_NUMBER() as en,ERROR_LINE() as el,ERROR_MESSAGE() as emsg,
ERROR_SEVERITY() as es 
end catch
done:
go


然后是创建队列 queue(一些具体的参数参见sql联机丛书吧,里面有详细说明)
create queue testqueue
with status = on,
retention = off,
activation(
status = off, --这里没有打开收到消息时执行的存储过程
procedure_name=dbo.processmsg,
max_queue_readers=5,
execute as self 
)


因为上面没有激活收到消息执行的存储过程,这里修改队列以激活它
alter queue testqueue
with status = on,
retention = off,
activation(
status = on,
procedure_name=dbo.processmsg,
max_queue_readers=5,
execute as self
)


最后create service
create service testservice
on queue testqueue(mtestcontract)


以上就是创建最基本的servicebroker需要执行的脚本,以上的脚本是在起始数据库上创建servicebroker的脚本,在目标服务器上的创建脚本略有不同:
一是处理接收消息的存储过程不同,因为这里目标服务器要对起始服务器进行消息的回发,并发出结束会话的消息(在消息会话处理结束时,一定要结束会话,不然会对性能造成严重影响)

use targetdb
go
create proc processmsg
as
declare 
@msgtype varchar(255),
@msgbody varchar(255),
@cid uniqueidentifier
begin try
begin tran
waitfor(
/*You can also specify a WHERE clause in the RECEIVE statement, but it is not a full-featured WHERE
clause. You can only specify a conversation_handle or conversation_group_id.*/
receive top(1)
@msgtype=message_type_name,
@msgbody=case when validation='N'
then cast(message_body as varchar(255))
end,
@cid=conversation_handle
from dbo.testqueue),timeout 3000
if(@@ROWCOUNT = 0 or @@ERROR <> 0)
begin
rollback tran
goto done
end
else
begin
if @msgtype = 'mtesttype'
begin
insert into t2(Msg,Cid,Mtype) values(@msgbody,@cid,@msgtype);
send on conversation @cid
message type mtesttype1('p1 has received ur msg,test ok');
end
end conversation @cid
end
commit tran
end try
begin catch
while(@@TRANCOUNT > 0) rollb

你可能感兴趣的:(SQLSERVER,SqlServer,Service,service,broker)