Sql server 2008 r2 SQL Server 2008 Service Broker教程--无法接收消息(传输状态异常)

Sql server 2008 r2 SQL Server 2008 Service Broker教程--无法接收消息(传输状态异常),sql-server-2008-r2,service-broker,Sql Server 2008 R2,Service Broker,我正在学习如何使用SQLServer2008R2的服务代理。当遵循教程时。之后,我成功地创建了消息类型、契约、队列和服务。之后,我可能已经发送了消息。但是,当尝试接收消息时,我得到的是ReceivedRequestMsg的空值,而不是发送的内容 查看系统传输队列时,消息的传输状态显示: 将消息排入目标队列时发生异常。错误:15517,状态:1。无法作为数据库主体执行,因为主体“dbo”不存在,无法模拟此类型的主体,或者您没有权限 我使用Windows登录名安装了SQL Server,如Mycom

我正在学习如何使用SQLServer2008R2的服务代理。当遵循教程时。之后,我成功地创建了消息类型、契约、队列和服务。之后,我可能已经发送了消息。但是,当尝试接收消息时,我得到的是
ReceivedRequestMsg
的空值,而不是发送的内容

查看系统传输队列时,消息的传输状态显示:

将消息排入目标队列时发生异常。错误: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\U 50.SQL\U PRIKRYL05\MSSQL)

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

  • SQL Server Management Studio必须以“管理员”身份启动,以便以后能够附加数据。然后我连接了SQL Server

  • 右键单击数据库,关联菜单“附加…”,按钮“添加…”,指向AdventureWorks2008R2_Data.mdf+OK。然后从下面的网格中选择AdventureWorks2008R2_Log.ldf(报告为未找到),然后按删除。。。按钮按“确定”后,将连接数据库,并自动创建AdventureWorks2008R2_log.LDF

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


    • 然后,在本教程之后,执行以下查询以创建消息类型、契约、队列和服务:

    到目前为止,一切顺利

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

    • 发送消息时,问题会显现出来:

    开始交易;
    开始对话@InitDlgHandle
    从服务
    [//AWDB/1DBSample/InitiatorService]
    服务
    N'//AWDB/1DBSample/TargetService'
    合同上
    [//AWDB/1DBSample/SampleContract]
    具有
    加密=关闭;
    选择@RequestMsg=
    N‘目标服务信息’;
    发送对话@InitDlgHandle
    消息类型
    [//AWDB/1DBSample/RequestMessage]
    (@RequestMsg);
    选择@RequestMsg作为SentRequestMsg;
    提交事务;
    去
    

    查看队列时,
    Initiator…
    Target…
    队列是空的,发送的消息可以在
    sys.transmission\u queue
    中找到,通过
    transmission\u status
    报告上述错误,您需要将目标队列上的receive授予登录名。它应该会起作用

    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
    
    将数据库上的授权:[]更改为[sa];
    
    executeas基础结构需要
    dbo
    映射到有效的登录名。ServiceBroker使用ExecuteAS基础结构来传递消息。遇到此问题的一个典型场景是在家工作时使用公司笔记本电脑。您使用缓存凭据登录到笔记本电脑,并使用相同的Windows缓存凭据登录到SQL。您发出一个
    CREATE DATABASE
    ,并且
    dbo
    被映射到您的公司域帐户。但是,“执行为基础结构”无法使用Windows缓存帐户,它需要直接连接到Active Directory。令人恼火的是,第二天在办公室一切正常(你的笔记本电脑又进入了公司网络,可以访问广告…)。你晚上回家,继续第三课。。。突然间,它就不起作用了。使整个事情看起来脆弱和不可靠。事实上,广告的连接性是必要的

    导致相同问题的另一种情况是,数据库在还原或附加时返回其创建者的SID(发出
    创建数据库
    的Windows登录名)。如果在创建数据库并将数据库复制/附加到PC2时使用了本地帐户
    PC1\Fred
    ,则该帐户在PC2上无效(当然,它的作用域是PC1)。同样,影响不大,但按原样执行,这会导致ServiceBroker给出您看到的错误

    最后一个例子是,当DB是由后来离开公司的用户创建的,并且广告帐户被删除。他似乎是在报复,但他是无辜的。生产数据库停止工作,只是因为
    dbo
    映射的也是他的SID。有趣


    只需将
    dbo
    更改为
    sa
    登录,您就可以修复整个执行过程,所有依赖于它的移动部件(SSB可能是最大的依赖项)开始工作。

    感谢您的更正;)你查过了吗?我正在使用sa user执行@RGI:我确实尝试过类似的启动程序,而且效果很好。问题是我
    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  
    
    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
    
    alter authorization on database::[<your_SSB_DB>] to [sa];