首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Server 2008 Service教程--无法接收消息(transmission_status中的异常)

Server 2008 Service教程--无法接收消息(transmission_status中的异常)
EN

Stack Overflow用户
提问于 2012-07-08 12:27:25
回答 2查看 22K关注 0票数 26

我正在学习如何使用Server 2008 R2的Service。在遵循教程时,在单个数据库中完成会话。在第一课之后,我成功地创建了消息类型、契约、队列和服务。在第二课之后,我可能已经发送了这个消息。但是,在尝试接收消息时,我得到的是ReceivedRequestMsg的NULL,而不是发送的内容。

当查看sys.transmission_queue时,消息的transmission_status说:

在目标队列中排队时发生异常。错误: 15517,状态: 1.不能作为数据库主体执行,因为主体"dbo“不存在,不能模拟这种类型的主体,或者您没有权限。

我已经使用像Mycomp\Petr这样的Windows登录来安装Server。我也在用那个登录来上课。

你能猜出是什么问题吗?我应该检查什么,或者设置什么来让它工作?

编辑的2012/07/16:帮助再现问题,以下是我所做的。如果您遵循下面的步骤,您能再现错误吗?

首先,我使用的是Windows7Enterprise SP1,以及Microsoft 2008 R2,Developer,64位(ver ).10.50.2500.0,根目录位于C:\Program \Microsoft Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL)。

  1. 按照本教程的建议,我下载了Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf示例数据库,并将其复制到C:\Program \Microsoft Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf中
  2. 为了以后能够附加数据,必须启动“作为管理员”的。然后我连接了Server。
  3. 右键单击数据库,上下文菜单附加.,按钮添加.,指向AdventureWorks2008R2_Data.mdf + OK。然后从下面的网格中选择AdventureWorks2008R2_Log.ldf (报告为未找到)并按下移除.按钮。按OK后,数据库被附加,AdventureWorks2008R2_log.LDF被自动创建。
  4. 以下查询用于查看"Service已启用/禁用“和启用( Service已成功地启用数据库):
代码语言:javascript
复制
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
  • 然后,在本教程之后,执行以下查询以创建消息类型、契约、队列和服务:
代码语言:javascript
复制
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

到现在为止还好。

  • 然后使用以下查询查看队列(现在使用时为空):
代码语言:javascript
复制
USE AdventureWorks2008R2;
GO

SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
  • 在发送消息时会出现问题:
代码语言:javascript
复制
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报告上述错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-19 13:12:49

代码语言:javascript
复制
alter authorization on database::[<your_SSB_DB>] to [sa];

执行作为基础结构需要dbo映射到有效的登录名。Service使用EXECUTE作为基础结构来传递消息。遇到这个问题的一个典型场景是在家里工作的公司笔记本电脑。使用缓存凭据登录到膝上型计算机,使用相同的Windows缓存凭据登录到SQL。您发出一个CREATE DATABASEdbo将映射到您的公司域帐户。但是,执行作为基础设施不能使用Windows缓存帐户,它需要直接连接到Active。令人恼火的是,第二天在办公室里一切都很顺利(你的笔记本电脑又在公司网络上,可以访问AD.)。你晚上回家,继续第三课.突然之间就不起作用了。让整件事看起来脆弱和不可靠。只是AD需要的事实..。

导致同样问题的另一个场景是,数据库在恢复或附加时重新启用其创建者的SID (发出CREATE DATABASE的Windows登录名)。如果在创建DB时使用本地帐户PC1\Fred,然后将数据库复制/附加到PC2,则PC2上的帐户无效(当然,它的作用域为PC1 )。同样,影响不大,但按原样执行,这会导致Service给出您看到的错误。

最后一个例子是DB是由用户创建的,用户稍后离开公司,然后删除AD帐户。似乎是他的报复,但他是无辜的。生产DB只是停止工作,仅仅是因为dbo映射的是他的SID。有趣..。

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

票数 51
EN

Stack Overflow用户

发布于 2012-07-12 19:24:52

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

代码语言:javascript
复制
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO

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

代码语言:javascript
复制
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
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11383145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档