Partilhar via


Removendo mensagens suspeitas

Aplica-se a:SQL ServerAzure SQL Managed Instance

Uma mensagem suspeita é uma mensagem que contém informações que um aplicativo não pode processar com êxito. Por exemplo, uma estação de trabalho de fabricação pode enviar uma solicitação para retirar uma peça do estoque pouco antes de uma ordem de alteração tornar a peça obsoleta. A ordem de alteração torna-se efetiva enquanto o pedido de inventário está em trânsito. O aplicativo de gerenciamento de estoque recebe a solicitação da estação de trabalho, mas não pode processá-la com êxito, e a operação do banco de dados para atualizar o número de peças em estoque falha. A transação que contém a operação de recebimento é então anulada, retornando a mensagem para a fila. Nessa situação, o aplicativo continua a receber a mesma mensagem, a atualização continua a falhar e a mensagem retorna para a fila.

Uma mensagem suspeita não é uma mensagem corrompida e pode não ser uma solicitação inválida. O Service Broker contém verificações de integridade de mensagens que detetam mensagens corrompidas. Normalmente, um aplicativo também valida o conteúdo de uma mensagem e descarta uma mensagem que contém uma solicitação ilegal. Em contraste, muitas mensagens venenosas eram válidas quando a mensagem foi criada, mas depois se tornaram impossíveis de processar.

Deteção automática de mensagens suspeitas

O Service Broker fornece deteção automática de mensagens envenenadas. Quando uma transação que contém uma instrução RECEIVE é revertida cinco vezes, o Service Broker desabilita todas as filas das quais a transação recebeu mensagens, definindo automaticamente o status da fila como OFF. Além disso, o Service Broker gera um evento do tipo Broker:Queue Disabled.

Um administrador pode usar alertas do SQL Server Agent para ser notificado quando uma fila estiver desabilitada. Um desenvolvedor também pode criar um aplicativo que deteta quando uma fila é desabilitada pelo Service Broker. Esse aplicativo geralmente inspeciona as mensagens na fila para encontrar a mensagem suspeita. Depois que o aplicativo determina qual mensagem não pode ser processada, o aplicativo define o status da fila como ON e termina a conversa para a mensagem com um erro. Um aplicativo que deteta mensagens maliciosas deve ser cuidadoso ao limpar qualquer estado associado à conversa quando esta termina. Para obter mais informações sobre como criar um aplicativo para se recuperar de mensagens envenenadas, consulte Manipulando mensagens envenenadas.

Removendo mensagens suspeitas administrativamente

A maioria dos aplicativos deve rastrear e remover mensagens suspeitas programaticamente. No entanto, às vezes pode ser necessário remover uma mensagem envenenada manualmente. Por exemplo, a parte do aplicativo que executa a recuperação pode não ser capaz de detectar a mensagem envenenada, ou pode não ser capaz de limpar com segurança o estado guardado para a conversa.

Remover uma mensagem manualmente corre o risco de interromper uma conversa importante. Portanto, sempre inspecione uma mensagem suspeita antes de remover a mensagem da fila. Para ver o conteúdo da mensagem, inicie uma transação, receba o corpo da mensagem, exiba o corpo da mensagem e reverta a transação. Até que você tenha certeza de que a mensagem em questão é uma mensagem suspeita, é importante reverter a transação.

Exemplo

O exemplo a seguir mostra como inspecionar uma mensagem com segurança para o identificador de conversa e29059bb-9922-40f4-a575-66b2e4c70cf9 na fila de espera ExpenseQueue.> [!NOTA]
> Os exemplos de código neste artigo foram testados usando o banco de dados de exemplo AdventureWorks2022, que pode descarregar da página inicial Microsoft SQL Server Samples and Community Projects.

    use AdventureWorks2008R2 ;
    GO

    -- Sample to show the content of a message, then return
    -- the message to the queue. This may be useful to determine
    -- whether a specific message cannot be processed due to the
    -- content of the message.

    -- Every exit path from the transaction rolls back the transaction.
    -- This code is intended to inspect the message, not remove the
    -- message from the queue permanently. The transaction must roll
    -- back to return the message to the queue.

    BEGIN TRANSACTION ;

      -- To print the body, the code needs the message_body and
      -- the encoding_format.

      DECLARE @messageBody VARBINARY(MAX),
              @validation NCHAR ;

      -- Receive the message. The WAITFOR handles the case where
      -- an application is attempting to process the message when
      -- this batch is submitted. Replace the name of the queue and
      -- the conversation_handle value.

      WAITFOR(
        RECEIVE TOP(1)
                @messageBody = message_body,
                @validation = validation
          FROM dbo.ExpenseQueue
          WHERE conversation_handle =
               'e29059bb-9922-40f4-a575-66b2e4c70cf9'
      ), TIMEOUT 2000 ;

      -- Roll back and exit if the message is not available
      -- in two seconds.

      IF @@ROWCOUNT = 0
        BEGIN
          ROLLBACK TRANSACTION ;
          PRINT 'No message available.' ;
          RETURN ;
        END

      -- Print the message based on the encoding format of
      -- the message body.

      IF (@validation = 'E')
        BEGIN
          PRINT 'Empty message.' ;
        END ;
      ELSE IF (@validation = 'X')
        BEGIN
          PRINT CONVERT(nvarchar(MAX), @messageBody) ;
        END ;
      ELSE IF (@validation = 'N')
        BEGIN
          PRINT 'No validation -- binary message:'
          PRINT @messageBody ;
        END

    ROLLBACK TRANSACTION
    GO

Quando você encontra uma mensagem venenosa, você termina a conversa. O exemplo a seguir termina a conversa e29059bb-9922-40f4-a575-66b2e4c70cf9.

    -- End the conversation. Do this only if the message cannot be
    -- processed by the normal procedure.

    END CONVERSATION 'e29059bb-9922-40f4-a575-66b2e4c70cf9'
        WITH ERROR = 127 DESCRIPTION = N'Unable to process message.' ;
    GO

Quando uma conversa termina, o Service Broker descarta as mensagens dessa conversa. Observe que a aplicação que normalmente processa a mensagem não recebe uma mensagem de EndDialog ou uma mensagem de erro para esta conversa. Portanto, se o aplicativo mantiver o estado, você deve ter cuidado para remover o estado associado à conversa depois de encerrar a conversa com um erro.

Se um serviço não puder processar uma mensagem, isso significa que o serviço não poderá concluir a tarefa da conversa. Encerrar a conversa com um erro notifica o outro participante da conversa de que a tarefa falhou.

Ver também