Компонент SQL Server Service Broker - время ожидания сообщения - PullRequest
1 голос
/ 29 августа 2011

Я исследую серверный брокер SQL Server как технологию обработки сообщений для нашего приложения.

В нашем сценарии сообщения, отправленные из одного клиентского приложения (WPF), должны быть поставлены в очередь в компоненте Service Broker, который будет получен другими клиентскими приложениями (Android). Сообщения чувствительны ко времени и должны быть получены получателем в течение «X» минут (например, 2 минуты) с момента их публикации в очереди, и если они не могут быть получены к тому времени, сообщения должны быть просрочены и удалены очереди.

Есть ли способ сообщить сервисному брокеру об истечении времени ожидания сообщения через "х" минут?

Редактировать: Добавлен скрипт, который я использую для проверки этого.

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

Ответы [ 2 ]

5 голосов
/ 29 августа 2011

Время жизни диалога можно указать в операторе BEGIN DIALOG:

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

Диалоговое окно должно завершиться (END обеими сторонами) в течение срока его службы, иначе произойдет ошибка. Таким образом, вы можете запустить диалог со сроком действия 2 минуты и отправить одно или несколько сообщений. Цель должна получить и обработать сообщение в течение этих 2 минут, иначе диалоговое окно выдаст ошибку.

Вы также можете использовать приоритеты разговора и отправлять чувствительные ко времени сообщения по каналу с более высоким приоритетом. Это гарантирует, что передача компонента Service Broker отдает приоритет вашим конфиденциальным сообщениям, а оператор RECEIVE клиентского приложения «всплывает» у сообщений с более высоким приоритетом, и они принимаются первыми.

3 голосов
/ 31 августа 2011

Альтернативный способ достижения того, чего вы хотите, без использования времени жизни диалога.

Отправьте «SentDate» в полезную нагрузку вашего сообщения и обработайте сообщения «просроченные» в вашей процедуре активации.Это дает вам возможность явно решить, что делать, когда срок действия сообщения истекает.(т.е. игнорирование сообщений с истекшим сроком действия, запись в таблицу ошибок, уведомление отправителя о том, какие сообщения поступают с опозданием и т. д.) *

...