SQL Server 2008中的Service Broker教程 - 不能接收消息(例外trans

2019-06-26 03:13发布

我正在学习如何使用SQL Server 2008 R2的Service Broker的。 当下面的教程完成单个数据库中一个对话 。 继第1课 ,我已经成功地创建了消息类型,合同,队列和服务。 继第2课 ,我可能已经发送的消息。 然而,试图收到消息的时候,我得到空的ReceivedRequestMsg而不是发送的内容。

当在看sys.transmission_queue ,该transmission_status的消息称:

而在目标队列入队的消息时发生异常。 错误:15517,状态:1无法执行作为数据库主要因为主体“DBO”不存在,这种类型的主体不能被冒充,或者您没有权限。

我已经安装使用Windows登录SQL Server等Mycomp\Petr 。 我使用的登录也为教训。

你能猜出这是什么问题? 我应该怎么检查和或者设置为使其工作?

编辑2012/07/16:帮助重现该问题,这里是我做的。 你能重现错误,如果你按照下面的步骤是什么?

首先,我使用的是Windows 7 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和按下删除...按钮。 按下确定后,数据库附着和AdventureWorks2008R2_log.LDF自动创建。

  4. 下面的查询被用于寻找“启用的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

Answer 1:

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

该EXECUTE AS基础设施需要dbo映射到一个有效的登录。 服务代理使用EXECUTE AS基础架构来提供消息。 运行到这个问题的一个典型情况是公司的笔记本电脑在家工作时。 您登录到使用缓存的凭据的笔记本电脑,而你使用相同的Windows缓存的凭据登录到SQL。 您发出CREATE DATABASEdbo被映射到您的企业域帐户。 但是,EXECUTE AS infrastructre 不能使用Windows缓存的帐户,它需要直接连接到Active Directory。 发狂的是,事情做工精细,第二天在办公室(你的笔记本电脑又是在公司内网中,并且可以访问到AD ...)。 你回家的晚上,继续进行第3课......和所有的突然不工作了。 使整个事情显得脆弱和不可靠。 仅仅是需要AD conectivity的事实...

这导致了同样的问题的另一个scenatio是一个事实,即数据库reteint他们的创造者的SID(Windows登录发出原因引起的CREATE DATABASE )恢复或连接时。 如果你使用一个本地帐户PC1\Fred在创建数据库,然后复制/数据库附加到PC2,该帐户是在PC2无效(它的作用范围是PC1,当然)。 同样,没有多少影响,但EXECUTE AS IS,这将导致服务代理给你看的错误。

而当被后来离开公司和AD帐户被删除的用户创建的DB最后一个例子。 好像从他的一部分报复,但他是无辜的。 生产DB刚刚停止工作,只是因为这是他的 SID的dbo映射了。 有趣的...

通过简单地改变dbosa登录您解决这整个EXECUTE AS的事情,所有依赖于它的运动部件(和SSB可能是最大的依赖)开始工作。



Answer 2:

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

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


文章来源: SQL Server 2008 Service Broker tutorial — cannot receive the message (exception in transmission_status)