web-dev-qa-db-ja.com

SQL Server 2008 Service Brokerチュートリアル-メッセージを受信できません(transmission_statusの例外)

SQL Server 2008 R2のService Brokerの使用方法を学習しています。チュートリアル 単一データベースでの会話の完了 に従う場合。 レッスン1 に続いて、メッセージタイプ、コントラクト、キュー、およびサービスを正常に作成しました。 レッスン2 に続いて、おそらくメッセージを送信しました。ただし、メッセージを受信しようとすると、送信されたコンテンツではなくReceivedRequestMsgのNULLが表示されます。

sys.transmission_queueを見ると、メッセージのtransmission_statusは次のように述べています。

ターゲットキューにメッセージをエンキューするときに例外が発生しました。エラー:15517、状態:1.プリンシパル「dbo」が存在しない、このタイプのプリンシパルが偽装できない、または権限がないため、データベースプリンシパルとして実行できません。

Mycomp\PetrのようなWindowsログインを使用してSQL Serverをインストールしました。レッスンにもそのログインを使用しています。

何が問題だと思いますか?機能させるには何を確認または設定する必要がありますか?

2012年7月16日編集:問題の再現を助けるために、ここで私がやったことをします。次の手順に従うと、エラーを再現できますか?

まず、Windows 7 Enterprise SP1、Microsoft SQL Server 2008 R2、Developer Edition、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を選択し([見つかりません]と報告されます)、[削除...]ボタンを押しました。 [OK]を押すと、データベースが接続され、AdventureWorks2008R2_log.LDFが自動的に作成されました。

  4. 次のクエリは、 "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
  • 次に、チュートリアルに従って、以下のクエリを実行して、メッセージタイプ、コントラクト、キュー、およびサービスを作成しました。

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を介して報告されます。

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

EXECUTE ASインフラストラクチャでは、有効なログインにマップするためにdboが必要です。 Service Brokerは、EXECUTE ASインフラストラクチャを使用してメッセージを配信します。この問題が発生する典型的なシナリオは、自宅で仕事をしているときの企業のラップトップです。キャッシュされた資格情報を使用してラップトップにログインし、同じWindowsキャッシュされた資格情報を使用してSQLにログインします。 CREATE DATABASEを発行すると、dboが企業ドメインアカウントにマッピングされます。ただし、EXECUTE AS infrastructre cannotはWindowsキャッシュアカウントを使用するため、Active Directoryへの直接接続が必要です。厄介なのは、翌日オフィスで問題なく機能することです(ラップトップは再び社内ネットワークにあり、ADにアクセスできます...)。夕方に家に帰ってレッスン3に進むと、突然突然機能しなくなります。全体が薄っぺらで信頼できないものに見えるようにします。 ADの接続性が必要であるという事実だけです...

同じ問題につながるもう1つの状況は、データベースが復元またはアタッチされたときに、作成者のSID(CREATE DATABASEを発行するWindowsログイン)を繰り返すという事実が原因です。ローカルアカウントPC1\Fredを使用してDBを作成し、データベースをPC2にコピー/アタッチした場合、アカウントはPC2では無効です(スコープはPC1です)。繰り返しますが、それほど影響はありませんが、EXECUTE ASは影響を受けます。これにより、Service Brokerが表示するエラーを発生させます。

最後の例は、後で退職するユーザーによってDBが作成され、ADアカウントが削除される場合です。彼からの復讐のようですが、彼は無実です。 dboもマッピングするhis SIDであるという理由だけで、本番DBは機能しなくなります。楽しい...

dboログインをsaログインに変更するだけで、このEXECUTE AS全体を修正し、それに依存するすべての可動部分(およびSSBがおそらく最大の依存関係)が機能し始めます。

47
Remus Rusanu

ターゲットキューでの受信をログインに許可する必要があります。そしてそれはうまくいくはずです!

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
5
Sergey