pep*_*epr 23 service-broker sql-server-2008-r2
我正在学习如何使用SQL Server 2008 R2的Service Broker.在完成单个数据库中的完成对话教程时.在第1课之后,我成功创建了消息类型,合同,队列和服务.在第2课之后,我可能已经发送了这条消息.但是,在尝试接收消息时,我获取的是NULL ReceivedRequestMsg而不是发送的内容.
在查看时sys.transmission_queue,transmission_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) .
按照教程建议,我下载了AdventureWorks2008R2_Data.mdf示例数据库,并将其复制到C:\ Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf
必须以"管理员"身份启动SQL Server Management Studio才能以后附加数据.然后我连接了SQL Server.
右键单击Databases,上下文菜单Attach ...,按钮Add ...,指向AdventureWorks2008R2_Data.mdf + OK.然后从下面的网格中选择AdventureWorks2008R2_Log.ldf(报告为未找到)并按下删除...按钮.按OK后,附加了数据库并自动创建了AdventureWorks2008R2_log.LDF.
以下查询用于查看"Service Broker enabled/disabled",以及启用(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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
USE AdventureWorks2008R2;
GO
SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
当在队列看时,Initiator...与Target...队列是空的,并且可见于所发送的消息sys.transmission_queue经由报告上述的错误transmission_status.
Rem*_*anu 47
alter authorization on database::[<your_SSB_DB>] to [sa];
Run Code Online (Sandbox Code Playgroud)
EXECUTE AS基础结构需要dbo映射到有效的登录名.Service Broker使用EXECUTE AS基础结构来传递消息.遇到此问题的典型方案是在家工作时使用公司笔记本电脑.您使用缓存凭据登录到笔记本电脑,然后使用相同的Windows缓存凭据登录到SQL.您发出a CREATE DATABASE并将dbogets映射到您的公司域帐户.但是,EXECUTE AS基础架构无法使用Windows缓存帐户,它需要直接连接到Active Directory.令人抓狂的部分是第二天办公室工作正常(你的笔记本电脑再次进入公司网络,可以访问AD ......).你晚上回家,继续第3课......突然间它不再起作用了.使整个事情看起来脆弱和不可靠.只是需要AD锥度的事实......
导致相同问题的另一种情况是由于数据库CREATE DATABASE在恢复或附加时重新创建其创建者的SID(发出的Windows登录名)这一事实.如果您PC1\Fred在创建数据库时使用本地帐户,然后将数据库复制/附加到PC2,则该帐户在PC2上无效(当然,它的范围是PC1).同样,受影响的并不多,但EXECUTE AS是,这会导致Service Broker给出您看到的错误.
最后一个例子是当用户创建数据库时,该用户稍后离开公司并删除AD帐户.似乎从他的部分复仇,但他是无辜的.生产DB刚刚停止工作,只是因为这是他的 SID的dbo地图了.有趣的...
通过简单地改变dbo来sa登录你解决这整个EXECUTE AS的事情,所有依赖于它的运动部件(和SSB可能是最大的依赖)开始工作.
您需要将目标队列的接收授予您的登录名.它应该工作!
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO
Run Code Online (Sandbox Code Playgroud)
而且您还需要为您的用户授予发送权限,目标服务的权限应该足够,但是让我们在将来启用这两项服务.
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20262 次 |
| 最近记录: |