学习使用 SQL Server2005 中 Service Broker的一点感受

这几天在学SQL Server 2005 中新提供的Service Broker,关于servic broker我能找到的资料有以下一些
MSDN 里有一篇 <<SQL Server 2005 Service Broker 初探>> 推荐
手上那本 胡百敬的 <<SQL Server 2005 开发详解释>>
Rickie Lee's blog  分类Sql Server 2005 里也有几篇比较有价值的文章
接着就是微软的 那2个WebCast  视频,
其他的中文资料,在Google,Baidu里找来找去,基本上多是采集 MSDN那篇(搞的我很郁闷)

在看了以上的资料后,我开始动手按上面给出的代码做起来
开始一切多挺顺利的, MSDN那个Hello World示例代码 复制下来就可以运行了,但当时对里面的几行代码比较困或
在Hello World 里建立了两个队列 HelloWorldTargetQueue,HelloWorldInitiatorQueue,以及与他们对应的服务
HelloWorldRequestService,HelloWorldResponseService.当时很困惑为什么 HellowWorldTargetQueue不与HelloWorldResponseService对应,因为Response动作一般由服务端发出(ASP做多了,呵呵),后来发现,在 Service Broker里两端是对等的,并且一个队例可以对应多个服务. 反正一句话可能作者搞错了,但是不影响运行...
这个例子在一个数据库里运行很顺利,但很多时候,我们可能需要在2个不同的数据库里运行,一个做为客户,一个做为服务,当你这么想时,你可能就会像我一样马上去尝试,但麻烦接着就来了,以至于我郁闷了3天,去解决着个问题
这3天里很多时间化在找资料上, 我的环境大至是这样的,在一个SQL 实例里(一台电脑上,一个...什么你不知道SQL实例是什么,那算我没说) 有2个数据库 S与C 现在要求,由C发消息到S数据库的Service Broker Service里(我也不想说的这么麻烦 -_")S的Serveic Broker在收到消息后,启动一个写好的存储过程来处理这些消息..(为什么你一点反映多没?以上这些操作可以是异步的,难道你一点多不觉的激动???,现在不用MSMQ,可以直接在数据库级别实现了!!,晕,还是没反映-_"")
我的代码是这样的:

S 数据库

Create Message Type XMLMessage

Validation = WELL_FORMED_XML

 

Create Contract XMLContract

(XMLMessage Sent by ANY)

--可以在声明队列时指定处理程序,详细见MSDN帮助(哈哈)

Create Queue ReceivingQueue With Status=ON, Retention=OFF

 

Create Service ReceivingService On Queue ReceivingQueue

(XMLContract)

 

C 数据库

Create Message Type XMLMessage

Validation = WELL_FORMED_XML

 

Create Contract XMLContract

(XMLMessage Sent by ANY)

 

Create Queue SendingQueue With Status=ON, Retention=OFF

 

Create Service SendingService On Queue SendingQueue

(XMLContract)

 

接着我们在C数据库里发送消息

 

Declare @xml_msg xml
Set @xml_msg='<xml>这是消息</xml>'
Declare @handle uniqueidentifier

Begin Dialog Conversation @handle

From Service SendingService
To Service 'ReceivingService'

On Contract XMLContract
WITH ENCRYPTION = OFF, LIFETIME = 100;


Send on Conversation @handle

Message Type XMLMessage

(@xml_msg);

End Conversation @handle

好了,点了一次,发送了,没有任何提示

接着在S:数据库里检测一下有没有收到

Select Cast(Message_Body as xml),* From S.dbo.ReceivingQueue

这位同学,你不要急着去试,以上代码我试了几百遍, S.dbo.ReceivingQueure里是没用任何消息!

为什么?因为2个不同的数据库之间发消息需要"路由",(什么路由?天那!)不要紧张,这个路由并不是你没搞清楚的那个路由,这个路由简单的说就是这样的

=========Copy 自Rickie Lee's blog 

1. Create a new route to the routing table for the current database ( initiator )
For outgoing messages, Service Broker determines routing by checking the routing table in the local database.
For example,
Use [Initiator DatabaseName]
CREATE ROUTE HelloRoute
    WITH
    SERVICE_NAME = 'SendingService',
    BROKER_INSTANCE = 'a727462b-52e7-4405-9eee-d19923729790',
    ADDRESS = 'LOCAL' ;
==========================================
很开心吧?问题终于解决了,,呵呵,没有...
正常人多知道[Initiator DatabaseName] 指的是发出消息的数据库也就是C数据库,SERVICE_NAME = 'SendingService'中'SendingService'指的是
发出消息数据库里的服务也就是C中的SendingService服务(From Service SendingService 你没看到吗)
但是,很郁闷作者笔误了(虽然他用键盘)
正确的是
在C:数据库下运行
CREATE ROUTE HelloRoute
    WITH
    SERVICE_NAME = 'ReceivingService',
    BROKER_INSTANCE = 'a727462b-52e7-4405-9eee-d19923729790',
    ADDRESS = 'LOCAL' ;
看清楚 是'ReceivingService'不是'SendingService',至于  'a727462b-52e7-4405-9eee-d19923729790'
你可以用:
SELECT service_broker_guid
FROM sys.databases
WHERE database_id = DB_ID('S') --是S哦!
得到,另外大家可以看到发消息时有如下句子(直接上面拷贝的你不知道!!)
From Service SendingService
To Service 'ReceivingService' --这里用'ReceivingService'
其实'ReceivingService'用字符串就是 用来在查询Select * From sys.routes Where Remote_service_name='ReceivingService'中找出对应的Broker_instance(详细信息看MSDN...)
好了,这下好了
再次发个看看,先去上个WC,洗手,接着祈祷,点了(F5),...成功了!!,哈哈
....郁闷还是不行,是那个
 
CREATE ROUTE HelloRoute
    WITH
    SERVICE_NAME = 'SendingService', 作者是对的?这位同学,你怎么一下子动摇了啊?
,(呵呵其实我当时,也这么想的)
但是,不是这个有问题?还会那里有问题?找找代码!很希望哪个单词拼错了(在面对未知时,人们总是有这样美好而简单--或说小白的希望)但2天下来...哎,您没看见吗,上面就那么几行代码,正常人多不会错的,于是就在网上寻求帮助,发Email,论坛发贴,什么"跪求"啊,"献身"啊,"跳楼"啊,...等字眼多在我发的贴的标题里出现了.....接着3天过去了(打开邮箱一看,...看来老师们,达人们,还有大虾们多很忙...反正没人回),论坛里我发的求救贴,好歹有几个人回了,不过,那几个人多偶本人,回的内容也就是一个字 '顶'.....
不搞了,见鬼去吧,以后用到了再说
接着就看到,
I spent quite a while trying to debug what's going on and I found that the topic in Books Online on "Troubleshooting Service Broker" and, particularly, "Troubleshooting Routing and Message Delivery" is excellent for helping with this
上面这些内容是在 Rickie Lee's blog  那片文章下面的一个引用地址里找到的,
他说可以在MSDN那个帮助里找到帮助,(废话,帮助,当然是帮助,要不就不叫帮助)
带着绝望的心情去看MSDN中 <<路由>>里的<<故障排除>>
发现有这么个东西sys.transmission_queue (什么你没找到?再找找)
当消息发送后你可以用 Select * From sys.transmission_queue 检查一下.如果查询结果是空,就表明消息很可能(是可能哦)成功发出去了,我运行这个查询后,在结果集中有这么一列 transmission_status,错误信息就显示在这一列 , 你可以在点发送后, 再点(运行) Select * From sys.transmission_queue 不要把这2个动作(上面的发消息,与Select * From sys.transmission_queue 这2个查询)放在一个批处理里...(为什么,为什么老爱问为什么呢??,你自己想想,反正,具体的我说不清楚)
我这里 transmission_status列里的消息是:
"An exception occurred while enqueueing a message in the target queue. Error: 916, State: 3. The server principal "sa" is not able to access the database "S" under the current security context."
==================传说中的分割线===========================
 
接着,又是,如此这样,这样如此, google,baidu ,哎,什么搜索引擎(搞个什么多不知道)
请原谅我当时确实很郁闷,在google,baidu搜寻了半天....最后去了MSDN的论坛我英文很菜,为什么非要我去鬼子的地方呢,对着词霸找到了下面这么一个贴子
 

It is indeed part of the SQL 2005 security lockdown. The details are explained in BOL  'Extending database impersonation using EXECUTE AS', http://msdn2.microsoft.com/en-us/library/ms188304.aspx

The easy fix is to make the database A trustworthy: ALTER DATABASE ... SET TRUSTWORTHY ON. If you don't trust the dbo of database a (doesn't seem to be the case, since is 'sa' from your message), then you'd have to use certificate based dialog security.

HTH,
~ Remus

特别地:The easy fix is to make the database A trustworthy: ALTER DATABASE ... SET TRUSTWORTHY ON.

当然,上面还有'Extending database impersonation using EXECUTE AS'

反正管不了那么多了

Alter Database C Set Trustworthy ON

Alter Database C Set Trunstworthy ON

再 Send 一下,也不WC, 洗手了,...如果还不能用就拉到了...

结果可以了, 汗~~~~~~

==================

以上就是这三天捣鼓的一点东西,写出来,希望有用,也给自己当学习笔记

刚开始学,不知道的东西很多,要继续努力了

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值