非同期通信を使用する分散アプリケーションを構築するための基本の1つは、次のように表現できます。イベントを積極的に待たないでください。このように、SQL Service Brokerに基づく自然な解決策は、キューに到着したメッセージによるストアドプロシージャのアクティブ化を使用することです。
レッスン2:公式のMicrosoftチュートリアルからの内部アクティベーションプロシージャの作成は、ストアドプロシージャをメッセージキューにバインドする方法を示しています。また、spを実装する方法も示しています。
(私はSQLを初めて使用します。しかしBEGIN
、の後にもうCREATE PROCEDURE... AS
1つ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
後(後)のため、ループは無限ではありません。ROLLBACK
TIMEOUT
データが到着した場合、BREAK
はスキップされます。予期されたメッセージが到着した場合、応答が返送されます。...EndDialog
or...Error
メッセージを受信すると、がEND CONVERSATION
実行されます。他の種類のメッセージもここで観察できますか?
いくつかのメッセージが到着した(そして処理された)と、トランザクションはコミットされます。
しかし、なぜ今ループするのですか?過去に通信回線が壊れたためにキューに詰まった他のメッセージを処理する意図はありますか?または、より多くのメッセージが一度に届き、それほど迅速に処理できなかったためですか?
別のメッセージがキューに入れられ、ストアドプロシージャがまだ実行されている場合はどうなりますか。その処理に別の作業プロセスが割り当てられていますか?別のストアドプロシージャを並行して起動できますか?はいの場合、なぜループですか?
助けてくれてありがとう、ペトル