2

私は、アプリケーションのメッセージ処理テクノロジとしてSQLServerサービスブローカーを研究しています。

このシナリオでは、1つのクライアントアプリケーション(WPF)から送信されたメッセージを、他のクライアントアプリケーション(android)が受信するサービスブローカーのキューに入れる必要があります。メッセージは時間に敏感であり、キューに投稿されてから「X」分(たとえば2分)以内に受信者が受信する必要があります。それまでに受信できない場合は、メッセージを期限切れにしてから削除する必要があります。列。

「x」分後にメッセージをタイムアウトするようにサービスブローカーに指示する方法はありますか?

編集:これをテストするために使用しているスクリプトを追加しました。

CREATE DATABASE ServiceBrokerTest
GO

ALTER DATABASE ServiceBrokerTest SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE 
GO

/****** Object:  MessageType [SampleMsgType] ***/
CREATE MESSAGE TYPE [SampleMsgType] AUTHORIZATION [dbo] VALIDATION = NONE
GO

/****** Object:  ServiceContract [MsgContract]    ******/
CREATE CONTRACT [MsgContract] AUTHORIZATION [dbo] ([SampleMsgType] SENT BY INITIATOR)
GO

/****** Object:  ServiceQueue [dbo].[Queue1]    ******/
CREATE QUEUE [dbo].[Queue1] WITH STATUS = ON , RETENTION = OFF , POISON_MESSAGE_HANDLING (STATUS = ON)  ON [PRIMARY] 
GO

/****** Object:  BrokerService [MsgService]    ******/
CREATE SERVICE [MsgService]  AUTHORIZATION [dbo]  ON QUEUE [dbo].[Queue1] ([MsgContract])
GO

/****** Object:  StoredProcedure [dbo].[SendMsg]  ******/
CREATE PROC [dbo].[SendMsg]
@msg NVARCHAR(MAX)
AS

BEGIN
    SET NOCOUNT ON
    DECLARE @handle UNIQUEIDENTIFIER

    BEGIN TRANSACTION
        BEGIN dialog @handle 
            FROM SERVICE [MsgService]
            TO SERVICE 'MsgService'
            ON CONTRACT [MsgContract]
            WITH ENCRYPTION = OFF, LIFETIME = 20

        ;SEND ON CONVERSATION @handle
            MESSAGE TYPE [SampleMsgType] (@msg)
        END CONVERSATION @handle
    COMMIT TRANSACTION
END

/****** Object:  StoredProcedure [dbo].[ReceiveMsg] ******/
CREATE PROC [dbo].[ReceiveMsg]
@msg NVARCHAR(MAX) OUT

AS

BEGIN
    SET NOCOUNT ON
    DECLARE @handle UNIQUEIDENTIFIER

    DECLARE @msgTable TABLE (
        handle UNIQUEIDENTIFIER,
        msg NVARCHAR(MAX),
        msgType VARCHAR(300));

    SET @handle = NULL

    WAITFOR (
        RECEIVE [conversation_handle], message_body, message_type_name
        FROM [dbo].[Queue1]
        INTO @msgTable
        ), TIMEOUT 25000

        SELECT @handle = handle
        FROM @msgTable
        WHERE msgType = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'

        IF @handle is not null
            BEGIN 
                END CONVERSATION @handle
            END

        SELECT @msg = msg
        FROM @msgTable
        WHERE msgType = 'SampleMsgType'
END 

GO
4

2 に答える 2

6

BEGIN DIALOGダイアログの存続期間は、ステートメント中に指定できます。

BEGIN DIALOG @handle
FROM SERVICE [...]
TO SERVICE '...'
ON CONTRACT [...]
, LIFETIME = <dialog lifetime>;

ダイアログは、その存続期間内に完了する必要があります(両側で終了)。そうでない場合、エラーが発生します。したがって、2分の有効期間でダイアログを開始し、その上で1つ以上のメッセージを送信できます。ターゲットはその2分以内にメッセージを受信して​​処理する必要があります。そうしないと、ダイアログでエラーが発生します。

会話の優先度を使用して、優先度の高いチャネルで時間に敏感なメッセージを送信することもできます。これにより、Service Brokerの送信で機密メッセージが優先され、クライアントアプリケーションのRECEIVEステートメントが優先度の高い時間機密メッセージを「バブルアップ」して最初に受信されるようになります。

于 2011-08-29T04:38:39.887 に答える
3

ダイアログの有効期間を使用せずに、目的を達成するための別の方法。

メッセージペイロードで「SentDate」を送信し、アクティベーション手順で「期限切れ」メッセージを処理します。これにより、メッセージの有効期限が切れたときに何をするかを明示的に決定できます。(つまり、期限切れのメッセージを無視する、エラーテーブルにログを記録する、どのメッセージが遅れて受信されているかを送信者に通知するなど)。

于 2011-08-30T22:59:55.563 に答える