Entfernen von nicht verarbeitbaren Nachrichten

Eine beschädigte Nachricht ist eine Nachricht, die Information enthält, die eine Anwendung nicht erfolgreich verarbeiten kann. Beispielsweise kann eine Fertigungsworkstation eine Anforderung absenden, ein Teil aus dem Lager zu holen, bevor dieses Teil durch eine Auftragsänderung hinfällig wird. Die Auftragsänderung wird wirksam, während die Lageranforderung übertragen wird. Die Lagerverwaltungsanwendung empfängt die Anforderung von der Workstation, kann die Anforderung aber nicht erfolgreich verarbeiten, und der Datenbankvorgang zum Aktualisieren der Anzahl von Teilen im Lager schlägt fehl. Für die Transaktion, die den Empfangsvorgang enthält, wird anschließend ein Rollback ausgeführt, und die Nachricht wird an die Warteschlange zurückgeschickt. In dieser Situation empfängt die Anwendung weiterhin dieselbe Nachricht, erzeugt die Aktualisierung weiterhin einen Fehler und wird die Nachricht an die Warteschlange zurückgeschickt.

Eine nicht verarbeitbare Nachricht ist keine beschädigte Nachricht und auch keine ungültige Anforderung. Service Broker enthält Nachrichtenintegritätsprüfungen, bei denen beschädigte Nachrichten erkannt werden. Auch eine Anwendung wertet normalerweise den Inhalt einer Nachricht aus und löscht eine Nachricht, die eine unzulässige Anforderung enthält. Auf der anderen Seite waren viele ungültige Nachrichten bei ihrer Erstellung gültig, konnten aber später nicht verarbeitet werden.

Automatische Erkennung ungültiger Nachrichten

Service Broker stellt automatische Erkennung von ungültigen Nachrichten bereit. Wenn für eine Transaktion, die eine RECEIVE-Anweisung enthält, fünfmal ein Rollback ausgeführt wird, deaktiviert Service Broker alle Warteschlangen, aus denen die Transaktion Nachrichten empfangen hat, indem der Warteschlangenstatus auf OFF festgelegt wird. Außerdem generiert Service Broker ein Ereignis des Typs Broker:Queue Disabled.

Ein Administrator kann mithilfe von Warnungen des SQL Server-Agents benachrichtigt werden, wenn eine Warteschlange deaktiviert wird. Ein Entwickler kann eine Anwendung erstellen, die erkennt, wenn eine Warteschlange von Service Broker deaktiviert wird. Diese Anwendung überprüft die Nachrichten in der Warteschlange oft, um beschädigte Nachrichten zu finden. Sobald die Anwendung erkennt, welche Nachricht nicht verarbeitet werden kann, legt sie den Warteschlangenstatus auf ON fest und beendet die Konversation für diese Nachricht mit einer Fehlermeldung. Eine Anwendung, die beschädigte Nachrichten erkennt, muss einen der Konversation zugeordneten Status bereinigen, wenn sie die Konversation beendet. Weitere Informationen zum Erstellen einer Anwendung zur Wiederherstellung bei beschädigten Nachrichten finden Sie unter Behandeln von nicht verarbeitbaren Nachrichten.

Administratives Entfernen beschädigter Nachrichten

Die meisten Anwendungen sollten beschädigte Nachrichten programmgesteuert nachverfolgen und entfernen. Manchmal kann es jedoch notwendig sein, eine solche Nachricht manuell zu entfernen. Beispielsweise könnte der Teil der Anwendung, von dem die Wiederherstellung ausgeführt wird, nicht in der Lage sein, die Nachricht zu erkennen oder den gespeicherten Zustand für die Konversation sicher zu bereinigen.

Das manuelle Entfernen einer Nachricht ist mit dem Risiko verbunden, eine wichtige Konversation zu unterbrechen. Überprüfen Sie daher eine beschädigte Nachricht immer, bevor Sie sie aus der Warteschlange entfernen. Beginnen Sie zum Anzeigen des Nachrichteninhalts eine Transaktion, empfangen Sie den Nachrichtentext, zeigen Sie ihn an, und führen Sie dann einen Rollback für die Transaktion aus. Solange Sie nicht sicher sind, dass es sich bei der fraglichen Nachricht um eine beschädigte Nachricht handelt, müssen Sie unbedingt einen Rollback für die Transaktion ausführen.

Beispiel

Im folgenden Beispiel wird dargestellt, wie eine Nachricht sicher auf den Konversationshandle e29059bb-9922-40f4-a575-66b2e4c70cf9 in der Warteschlange ExpenseQueue überprüft wird.

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

Wenn Sie eine beschädigte Nachricht finden, beenden Sie die Konversation. Im folgenden folgende Beispiel wird die Konversation e29059bb-9922-40f4-a575-66b2e4c70cf9 beendet.

-- 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

Wenn eine Konversation beendet wird, löscht Service Broker die Nachrichten für diese Konversation. Beachten Sie, dass die Anwendung, von der die Nachricht normalerweise verarbeitet wird, keine EndDialog- oder Error-Nachricht für diese Konversation empfängt. Wenn die Anwendung Statusinformationen verwaltet, müssen Sie daher darauf achten, den der Konversation zugeordneten Status nach Beendigung der Konversation mit einer Fehlermeldung zu entfernen.

Wenn ein Dienst eine Nachricht nicht verarbeiten kann, kann er die Aufgabe für die Konversation nicht abschließen. Wird die Konversation mit einem Fehler beendet, wird der andere Teilnehmer der Konversation darüber benachrichtigt, dass die Aufgabe einen Fehler erzeugt hat.