2

我们正在开发一个应用程序,它将使用服务代理将消息从一个数据库传输到另一个数据库。 SourceDB被一个现有的应用程序使用,我们从中抽取一些数据。 TargetDB仅由该应用程序使用并处理/分发我们需要的数据。我们只使用一种类型的合同,两个数据库都在同一台服务器上。

我们已经在两者以及各自的发起者和目标队列/服务上设置了相同的消息类型和合同。在两个数据库上:

  • ENABLE_BROKER已设置
  • TRUSTWORTHY已设置
  • 拥有独一无二的service_broker_guid
  • sa作为数据库所有者,所有 SSB 授权语句都是or dboOWNER视情况而定。

但是,当我们从 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
  • 传输队列为空
  • 无论是在 SQL Server 日志中,还是在创建消息的存储过程中的 CATCH 错误处理中,都没有记录错误
  • 如果启用激活,SourceDB 中的启动器队列条目sys.dm_broker_queue_monitors将设置为 NOTIFIED
  • SourceDB 的状态sys.conversation_endpoints有一个新条目CONVERSING
  • sys.dm_broker_queue_monitors如果启用激活,TargetDB 中的目标队列条目将保持为 INACTIVE
  • TargetDBsys.conversation_endpoints有一个新条目处于CONVERSING状态,与 SourceDB 的条目具有相同的 conversation_id 和不同的 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 跟踪,显示正在执行的命令正在//Service/TargetSourceDB 上查找。服务经纪人似乎不知何故感到困惑。添加显式路由,除了理论上是不必要的外,并不会改变这种情况。

我在我们的测试服务器上运行了一组几乎相同的教程命令,一切正常,所以它可能是特定于 db 的。

我们的设置在两天前工作,所以我们可能正在寻找一些可能已经更改但没有运气的设置。

4

0 回答 0