1

非同期通信を使用する分散アプリケーションを構築するための基本の1つは、次のように表現できます。イベントを積極的に待たないでください。このように、SQL Service Brokerに基づく自然な解決策は、キューに到着したメッセージによるストアドプロシージャのアクティブ化を使用することです。

レッスン2:公式のMicrosoftチュートリアルからの内部アクティベーションプロシージャの作成は、ストアドプロシージャをメッセージキューにバインドする方法を示しています。また、spを実装する方法も示しています。

(私はSQLを初めて使用します。しかしBEGIN、の後にもうCREATE PROCEDURE... AS1つEND、?の前にもう1つあるべきではありませんGO。)

私はそれを正確に理解していますか?コードの下の私の質問を参照してください...

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'//AWDB/InternalAct/RequestMessage'
    BEGIN
       DECLARE @ReplyMsg NVARCHAR(100);
       SELECT @ReplyMsg =
       N'<ReplyMsg>Message for Initiator service.</ReplyMsg>';
 
       SEND ON CONVERSATION @RecvReqDlgHandle
              MESSAGE TYPE 
              [//AWDB/InternalAct/ReplyMessage]
              (@ReplyMsg);
    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

メッセージが到着すると、プロシージャが呼び出され、「無限」ループに入ります。実際には、データが到着しなかったBREAK後(後)のため、ループは無限ではありません。ROLLBACKTIMEOUT

データが到着した場合、BREAKはスキップされます。予期されたメッセージが到着した場合、応答が返送されます。...EndDialogor...Errorメッセージを受信すると、がEND CONVERSATION実行されます。他の種類のメッセージもここで観察できますか?

いくつかのメッセージが到着した(そして処理された)と、トランザクションはコミットされます。

しかし、なぜ今ループするのですか?過去に通信回線が壊れたためにキューに詰まった他のメッセージを処理する意図はありますか?または、より多くのメッセージが一度に届き、それほど迅速に処理できなかったためですか?

別のメッセージがキューに入れられ、ストアドプロシージャがまだ実行されている場合はどうなりますか。その処理に別の作業プロセスが割り当てられていますか?別のストアドプロシージャを並行して起動できますか?はいの場合、なぜループですか?

助けてくれてありがとう、ペトル

4

1 に答える 1

5

内部アクティベーションはトリガーのようなものではありません。具体的には、アクティブ化されたプロシージャは、到着したメッセージごとに起動されません。代わりに、処理するものがあるときにプロシージャが起動され、SSBインフラストラクチャが進行状況を監視している間、メッセージを連続して(ループで)デキューし、必要に応じて、指定された最大数まで支援する2番目のプロシージャを起動します。キューモニターについてを参照してください。

アクティブ化されたプロシージャにループがあることは厳密には必須ではありません。ループがなくても問題なく動作するはずです。非常にビジーな環境では、ループのパフォーマンスが向上するはずです。この古いMSDNディスカッションも参照してください。

于 2012-08-13T15:04:22.807 に答える