我可以在SQL Server Service Broker的同一消息队列上运行两个存储过程吗?

时间:2017-04-27 22:43:20

标签: sql-server sql-server-2008 sql-server-2012 message-queue service-broker

我有一个填充多种类型消息的队列,我希望在同一个队列上运行两个存储过程,每个消息类型一个。

我不想要一个检查多种类型的人。

问题是,我看不到如何在队列定义中定义两个:

CREATE QUEUE MyQueue  WITH ACTIVATION
(
    STATUS = ON,
    -- How have two?
    PROCEDURE_NAME = [my_listener_proc],
    MAX_QUEUE_READERS = 4,
    EXECUTE AS SELF
)
GO

1 个答案:

答案 0 :(得分:0)

上面的评论有权 - 你只能获得一个激活程序。但是你可以在proc中放入逻辑来根据消息类型做其他事情。这是我在制作中略有编辑的版本:

ALTER PROCEDURE [repl].[myActivation]
AS
BEGIN
    DECLARE
        @message_type nvarchar(256),
        @message XML,
        @rc INT,
        @queuing_order BIGINT;
    DECLARE @messages TABLE (
        [message_type] sysname, 
        [message] XML
    );
    SET NOCOUNT ON;

    WHILE(1=1)
    BEGIN

        WAITFOR(
            RECEIVE TOP (1000)
                [message_type_name],
                CAST([message_body] AS XML)
            FROM [repl].[myQueue]
            INTO @messages
        ), TIMEOUT 5000;

        IF (@@rowCount = 0)
            BREAK;
        ELSE
        BEGIN

            DECLARE [messages] CURSOR FAST_FORWARD LOCAL
            FOR
            SELECT [message], [message_type]
            FROM @messages;

            OPEN [messages];
            WHILE(1=1)
            BEGIN
                FETCH NEXT FROM [messages] 
                INTO @message, @message_type;
                IF (@@fetch_Status <> 0)
                    BREAK;

                BEGIN TRY

                    IF (@message_type = 'A')
                    BEGIN
                        EXEC @rc = [repl].[ProcessAMessage] 
                            @message = @message;
                    END
                    ELSE IF (@message_type = 'B')
                    BEGIN
                        EXEC @rc = [repl].[ProcessBMessage]
                            @message = @message;
                    END 

                    IF (@rc <> 0)
                    BEGIN
                        INSERT INTO [repl].[DeadLetters]
                                ( [Payload], [MessageType] )
                        VALUES  ( @message, @message_type );
                    END
                END TRY
                BEGIN CATCH
                    INSERT INTO [repl].[DeadLetters]
                            ( [Payload], [MessageType] )
                    VALUES  ( @message, @message_type );
                END CATCH
            END
            CLOSE [messages];
            DEALLOCATE [messages];

            DELETE @messages;
        END
    END
END
GO

那里有一点点(除了根据消息类型路由到不同的proc),包括:

  • 一次接收多封邮件,以免过于频繁地锁定会话
  • 采取一些步骤确保激活程序不会回退/错误输出。毒药信息可能会破坏你的一天。

我没有使用我的交易,因为还有另一个流程可以确保应用消息的效果。因此,如果任何给定的消息成功,它并不重要(因为它不会被相对快速地检测到)。