我们正在开发一个应用程序,它将使用服务代理将消息从一个数据库传输到另一个数据库。 SourceDB 由现有应用程序使用,我们从中吸取一些数据。 TargetDB 仅由此应用程序使用,并处理/分发我们需要的数据。我们只使用一种类型的合同,两个数据库都在同一台服务器上。
我们已在两者以及相应的发起人和目标队列/服务上设置了相同的消息类型和合同。在两个数据库上:
ENABLE_BROKER
已设置TRUSTWORTHY
已设置service_broker_guid
sa
作为数据库所有者,所有SSB授权声明均视为dbo
或OWNER
。但是,当我们从SourceDB发送消息时:
BEGIN DIALOG CONVERSATION @dialogHandle
FROM SERVICE [//Service/Initiator]
TO SERVICE N'//Service/Target'
ON CONTRACT [//Contract/Notification]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @dialogHandle
MESSAGE TYPE [//Message/Notification] (@RequestMsg);
...消息找不到他们的路。进一步调查揭示了以下内容:
RECEIVE
)sys.dm_broker_queue_monitors
中的启动器队列条目设置为NOTIFIED sys.conversation_endpoints
在CONVERSING
州sys.dm_broker_queue_monitors
中的目标队列条目仍然是不活动的sys.conversation_endpoints
在CONVERSING
状态中有一个新条目,具有相同的conversation_id和来自SourceDB条目的不同conversation_handle 虽然测试数据库是SQL 2005(应用程序必须支持2005),但我从开发机器的2008安装中运行ssbdiagnose实用程序来解决问题:
ssbdiagnose -S testserver -d SourceDB CONFIGURATION FROM SERVICE //Service/Initiator TO SERVICE //Service/Target ON CONTRACT //Contract/Notification
这产生了以下结果:
D 29912 dbtestsvr SourceDB Service //Service/Target was not found
D 29975 dbtestsvr SourceDB User dbo does not have SEND permission on service //Service/Target
这很令人困惑,因为dbo
不应该被拒绝任何权限,//Service/Target
肯定存在,尽管在不同的数据库中。但我的同事运行了一个Profiler跟踪,显示正在执行的命令在SourceDB上查找//Service/Target
。服务经纪人似乎在某种程度上感到困惑。除了在理论上不必要之外,添加显式路由不会改变这种情况。
我在测试服务器上运行了一组几乎相同的tutorial commands,一切正常,所以很可能是db特有的。
我们的设置在两天前开始工作,所以我们可能正在寻找一些可能已经改变的设置,但没有运气。