2017-09-13 12 views
0

私は、スケジュールに従って毎日実行されるバックアップ手順(本番)を持っており、生成されたバックアップは下位環境をリフレッシュするために定期的に使用されます。私は下位環境(別のサーバー)に.bakファイルをダウンロードする自動化ソリューションを構築しています。私はミラーからオプションをバックアップに使用することを嫌っています。これはミラーリングに失敗した場合に通常のバックアップ操作を実行する可能性があるためです。ここでは、サービスブローカを使用して、バックアップ手順の最後にprodからless環境にファイルコピーを非同期にトリガしたいと考えています。私は、サービスブローカー、メッセージタイプ、サービス、待ち行列および契約を理解するのに多くの努力を払ってきました。ここまではすべてが問題ありません。今度は、サービスブローカを使用してバックアップの最後にカスタムロジックを使用してファイルコピープロシージャをトリガする方法を理解したいだけです。私はサービスブローカーを理解するために、以下のスクリプトで遊んだ。誰かが親切にこのことから解決策を構築する方法を教えてくれます。SQL Serverのサービスブローカーを使用した非同期プロシージャコール

------------------------------------------------------------SETUP-------------------------------------------- 

CREATE MESSAGE TYPE [//SBTest/SBSample/RequestMessage] VALIDATION=WELL_FORMED_XML; 

CREATE MESSAGE TYPE [//SBTest/SBSample/ReplyMessage] VALIDATION=WELL_FORMED_XML; 
------------------------------------------------------------------------------------------------------------- 
CREATE CONTRACT [//SBTest/SBSample/SBContract] 
(
[//SBTest/SBSample/RequestMessage] SENT BY INITIATOR , 
[//SBTest/SBSample/ReplyMessage] SENT BY TARGET 
); 
------------------------------------------------------------------------------------------------------------- 
CREATE QUEUE SBInitiatorQueue; 

CREATE QUEUE SBTargetQueue; 
------------------------------------------------------------------------------------------------------------- 
CREATE SERVICE [//SBTest/SBSample/SBInitiatorService] ON QUEUE SBInitiatorQueue; 

CREATE SERVICE [//SBTest/SBSample/SBTargetService] ON QUEUE SBTargetQueue ([//SBTest/SBSample/SBContract]); 

------------------------------------------------------------------------------------------------------------- 





-------------------------------------------------------INITIATE QUE----------------------------------------- 
DECLARE @InitDlgHandle UNIQUEIDENTIFIER 
DECLARE @RequestMessage VARCHAR(1000) 

BEGIN TRAN 

--Determine the Initiator Service, Target Service and the Contract 

BEGIN DIALOG @InitDlgHandle 
FROM SERVICE [//SBTest/SBSample/SBInitiatorService] TO SERVICE'//SBTest/SBSample/SBTargetService' 
ON CONTRACT 
[//SBTest/SBSample/SBContract] 
WITH ENCRYPTION=OFF; 


--Prepare the Message 
SELECT @RequestMessage = N'HAHA'; 


--Send the Message 
SEND ON CONVERSATION @InitDlgHandle 
MESSAGE TYPE 
[//SBTest/SBSample/RequestMessage] 
(@RequestMessage); 

SELECT @RequestMessage AS SentRequestMessage; 

COMMIT TRAN 
--------------------------------------------------------------------------------------------------------------- 






-------------------------------------------------------READ QUE------------------------------------------------- 

\DECLARE @TargetDlgHandle UNIQUEIDENTIFIER 
DECLARE @ReplyMessage VARCHAR(1000) 
DECLARE @ReplyMessageName Sysname 

BEGIN TRAN; 

--Receive message from Initiator 
RECEIVE TOP(1) 
@TargetDlgHandle=Conversation_Handle, @ReplyMessage=Message_Body, @ReplyMessageName=Message_Type_Name 
FROM SBTargetQueue; 

SELECT @ReplyMessage AS ReceivedRequestMessage; 

-- Confirm and Send a reply 
IF @ReplyMessageName=N'HAHA' 

BEGIN 
DECLARE @RplyMsg VARCHAR(1000) 

SELECT @RplyMsg =N'HI'; 

SEND ON CONVERSATION @TargetDlgHandle 
MESSAGE TYPE 
[//SBTest/SBSample/ReplyMessage] 
(@RplyMsg); 
END CONVERSATION @TargetDlgHandle; 

END 

SELECT @RplyMsg AS SentReplyMessage; 

COMMIT TRAN; 

------------------------------------------------------------------------------------------------------------------- 

答えて

2

トリガーは、「内部アクティベーション」を使用して行われます。メッセージがキューに入ったときにトリガされるストアドプロシージャを作成し、キューから読み込んでから作業を行う必要があります。 はlinkから適応:

CREATE PROCEDURE TargetActivProc 
AS 
    DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; 
    DECLARE @RecvReqMsg NVARCHAR(100); 
    DECLARE @RecvReqMsgName sysname; 

    WHILE (1=1) 
    BEGIN 

    BEGIN TRANSACTION; 

    WAITFOR 
    (RECEIVE TOP(1) 
     @RecvReqDlgHandle = conversation_handle, 
     @RecvReqMsg = message_body, 
     @RecvReqMsgName = message_type_name 
     FROM TargetQueueIntAct 
    ), TIMEOUT 5000; 

    IF (@@ROWCOUNT = 0) 
    BEGIN 
     ROLLBACK TRANSACTION; 
     BREAK; 
    END 

    IF @RecvReqMsgName = 
     N'//SBTest/SBSample/RequestMessage' 
    BEGIN 

     --do work here 
    END 
    ELSE IF @RecvReqMsgName = 
     N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 
    BEGIN 
     END CONVERSATION @RecvReqDlgHandle; 
    END 
    ELSE IF @RecvReqMsgName = 
     N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' 
    BEGIN 
     END CONVERSATION @RecvReqDlgHandle; 
    END 

    COMMIT TRANSACTION; 

    END 
GO 

次の部分は、手順は、メッセージがキューに到着したときに活性化されるとまでは活性化ループままになりキュー

ALTER QUEUE SBTargetQueue 
    WITH ACTIVATION 
    (STATUS = ON, 
     PROCEDURE_NAME = TargetActivProc, 
     MAX_QUEUE_READERS = 1, 
     EXECUTE AS SELF 
    ); 

上の活性化を可能にすることですキューは空です。

+0

リチャードカップル しばらくの間、キューが空になると、それが再びトリガされますか?キュー内の新しいメッセージがトリガしますか? – TharunRaja

+0

@TharunRajaそれは正しいです。キューにメッセージがある限り、SQL Serverはアクティブ化されたプロセスの数が

+0

私はalter queueスクリプトを試してみましたが、ダミーのテーブルに挿入するランダムなプロシージャー名を付けました。ときには、キューにメッセージがあるときにキューに添付されたプロシージャが実行され、実行されないことがあることがあります。 MAX_QUEUE_READERSオプションとキュー内のメッセージ数は何ですか?あなたの答えは私にサービスブローカーの理解を助けました。ありがとうございました。 – TharunRaja

関連する問題