26

我正在学习如何使用 SQL Server 2008 R2 的 Service Broker。按照教程在单个数据库中完成对话时。按照第 1 课,我成功地创建了消息类型、合同、队列和服务。在第 2 课之后,我可能已经发送了消息。但是,当尝试接收消息时,我得到的是 NULLReceivedRequestMsg而不是发送的内容。

在查看 时sys.transmission_queuetransmission_status消息中显示:

在目标队列中排队消息时发生异常。错误:15517,状态:1。无法作为数据库主体执行,因为主体“dbo”不存在,无法模拟此类主体,或者您没有权限。

我已经使用 Windows 登录安装了 SQL Server,例如Mycomp\Petr. 我也在使用该登录名来上课。

你能猜出是什么问题吗?我应该检查和/或设置什么以使其正常工作?

2012/07/16 编辑:为了帮助重现问题,这就是我所做的。如果您按照以下步骤操作,您能否重现该错误?

首先,我使用的是 Windows 7 Enterprise SP1 和 Microsoft SQL Server 2008 R2,开发人员版,64 位(版本 10.50.2500.0,根目录位于 C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL) .

  1. 按照教程的建议,我下载了 AdventureWorks2008R2_Data.mdf 示例数据库,并将其复制到 C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf

  2. SQL Server Management Studio 必须以“以管理员身份”启动才能稍后附加数据。然后我连接了 SQL Server。

  3. 右键单击数据库,上下文菜单附加...,按钮添加...,指向 AdventureWorks2008R2_Data.mdf + OK。然后从下面的网格中选择 AdventureWorks2008R2_Log.ldf(报告为 Not found)并按下 Remove... 按钮。按 OK 后,附加数据库并自动创建 AdventureWorks2008R2_log.LDF。

  4. 以下查询用于查看“Service Broker 启用/禁用”和启用(已为数据库成功启用 Service Broker):


USE master;
GO

SELECT name, is_broker_enabled FROM sys.databases;
GO

ALTER DATABASE AdventureWorks2008R2
      SET ENABLE_BROKER
      WITH ROLLBACK IMMEDIATE;
GO

SELECT name, is_broker_enabled FROM sys.databases;
GO
  • 然后,按照教程,执行以下查询以创建消息类型、合同、队列和服务:

USE AdventureWorks2008R2;
GO

CREATE MESSAGE TYPE
       [//AWDB/1DBSample/RequestMessage]
       VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
       [//AWDB/1DBSample/ReplyMessage]
       VALIDATION = WELL_FORMED_XML;
GO

CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
      ([//AWDB/1DBSample/RequestMessage]
       SENT BY INITIATOR,
       [//AWDB/1DBSample/ReplyMessage]
       SENT BY TARGET
      );
GO

CREATE QUEUE TargetQueue1DB;

CREATE SERVICE
       [//AWDB/1DBSample/TargetService]
       ON QUEUE TargetQueue1DB
       ([//AWDB/1DBSample/SampleContract]);
GO

CREATE QUEUE InitiatorQueue1DB;

CREATE SERVICE
       [//AWDB/1DBSample/InitiatorService]
       ON QUEUE InitiatorQueue1DB;
GO

到现在为止还挺好。

  • 然后使用以下查询来查看队列(现在使用时为空):

USE AdventureWorks2008R2;
GO

SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
  • 发送消息时会出现问题:

BEGIN TRANSACTION;

BEGIN DIALOG @InitDlgHandle
     FROM SERVICE
      [//AWDB/1DBSample/InitiatorService]
     TO SERVICE
      N'//AWDB/1DBSample/TargetService'
     ON CONTRACT
      [//AWDB/1DBSample/SampleContract]
     WITH
         ENCRYPTION = OFF;

SELECT @RequestMsg =
       N'<RequestMsg>Message for Target service.</RequestMsg>';

SEND ON CONVERSATION @InitDlgHandle
     MESSAGE TYPE 
     [//AWDB/1DBSample/RequestMessage]
     (@RequestMsg);

SELECT @RequestMsg AS SentRequestMsg;

COMMIT TRANSACTION;
GO  

在查看队列时,Initiator...Target...队列是空的,并且可以在发送的消息中找到sys.transmission_queue上面提到的通过transmission_status.

4

2 回答 2

51
alter authorization on database::[<your_SSB_DB>] to [sa];

EXECUTE AS 基础设施需要dbo映射到一个有效的登录。Service Broker 使用 EXECUTE AS 基础架构来传递消息。遇到此问题的典型场景是在家工作时使用公司笔记本电脑。您使用缓存凭据登录笔记本电脑,并使用相同的 Windows 缓存凭据登录 SQL。您发出 aCREATE DATABASE并将其dbo映射到您的公司域帐户。但是,EXECUTE AS 基础设施不能使用 Windows 缓存帐户,它需要直接连接到 Active Directory。令人抓狂的部分是第二天在办公室一切正常(您的笔记本电脑再次在公司网络中并且可以访问 AD ......)。你晚上回家,继续第 3 课……突然间,它不再起作用了。让整个事情显得脆弱和不可靠。只是需要AD连接的事实......

导致相同问题的另一种情况是由于数据库CREATE DATABASE在恢复或附加时重新保留其创建者的 SID(发出 的 Windows 登录名)。如果您PC1\Fred在创建数据库时使用了本地帐户,然后将数据库复制/附加到 PC2,则该帐户在 PC2 上无效(当然,它的范围是 PC1)。同样,影响不大,但 EXECUTE AS 是,这会导致 Service Broker 给出您看到的错误。

最后一个示例是当数据库由后来离开公司的用户创建并且 AD 帐户被删除时。似乎是对他的报复,但他是无辜的。生产数据库停止工作,仅仅是因为映射的也是他的SID 。dbo乐趣...

通过简单地更改dbo登录sa,您可以修复整个 EXECUTE AS 事情,并且所有依赖它的移动部件(SSB 可能是最大的依赖项)开始工作。

于 2012-07-19T13:12:49.903 回答
5

您需要将目标队列上的接收授予您的登录。它应该工作!

USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO

而且您还需要为您的用户授予发送权限,目标服务的权限应该足够了,但是让我们在未来启用这两个服务。

USE AdventureWorks2008R2 ;
GO

GRANT SEND ON SERVICE::[//AWDB/1DBSample/InitiatorService]
TO [Mycomp\Petr] ;
GO

GRANT SEND ON SERVICE::[//AWDB/1DBSample/TargetService]
TO [Mycomp\Petr] ;
GO
于 2012-07-12T19:24:52.503 回答