Gifberichten verwijderen

van toepassing op:SQL ServerAzure SQL Managed Instance

Een gifbericht is een bericht met informatie die een toepassing niet kan verwerken. Een productiewerkstation kan bijvoorbeeld een aanvraag indienen om een onderdeel uit de voorraad in te trekken vlak voordat een wijzigingsvolgorde het onderdeel verouderd maakt. De wijzigingsvolgorde wordt van kracht terwijl de aanvraag voor voorraad onderweg is. De voorraadbeheertoepassing ontvangt de aanvraag van het werkstation, maar kan de aanvraag niet verwerken en de databasebewerking om het aantal onderdelen op voorraad bij te werken mislukt. De transactie met de ontvangstbewerking wordt vervolgens teruggedraaid en retourneert het bericht naar de wachtrij. In dit geval blijft de toepassing hetzelfde bericht ontvangen, blijft de update mislukken en wordt het bericht teruggezet naar de wachtrij.

Een gifbericht is geen beschadigd bericht en is mogelijk geen ongeldig verzoek. Service Broker bevat integriteitscontroles voor berichten die beschadigde berichten detecteren. Een toepassing valideert doorgaans ook de inhoud van een bericht en negeert een bericht dat een ongeldige aanvraag bevat. Daarentegen waren veel gifberichten geldig toen het bericht werd gemaakt, maar later werd het onmogelijk om te verwerken.

Automatische detectie van gifberichten

Service Broker biedt automatische detectie van gifberichten. Wanneer een transactie die een RECEIVE-instructie bevat, vijf keer terugdraait, schakelt Service Broker alle wachtrijen uit van waaruit de transactie berichten heeft ontvangen door de wachtrijstatus automatisch in te stellen op OFF. Daarnaast genereert Service Broker een gebeurtenis van het type Broker:Queue Disabled.

Een beheerder kan sql Server Agent-waarschuwingen gebruiken om een melding te ontvangen wanneer een wachtrij is uitgeschakeld. Een ontwikkelaar kan ook een toepassing maken die detecteert wanneer een wachtrij is uitgeschakeld door Service Broker. Die toepassing inspecteert vaak de berichten in de wachtrij om het gifbericht te vinden. Zodra de toepassing bepaalt welk bericht niet kan worden verwerkt, stelt de toepassing de wachtrijstatus ON in en beëindigt het gesprek voor het bericht met een fout. Een toepassing die gifberichten detecteert, moet voorzichtig zijn met het opschonen van alle statussen die aan het gesprek zijn gekoppeld bij het beëindigen van het gesprek. Zie Gifberichten verwerken voor meer informatie over het maken van een toepassing om te herstellen van gifberichten.

Gifberichten beheersmatig verwijderen

De meeste toepassingen moeten gifberichten programmatisch bijhouden en verwijderen. Het kan echter soms nodig zijn om handmatig een gifbericht te verwijderen. Het deel van de toepassing dat herstel uitvoert, kan bijvoorbeeld het gifbericht niet detecteren of kan de opgeslagen status voor het gesprek niet veilig opschonen.

Als u een bericht handmatig verwijdert, loopt u het risico dat een belangrijk gesprek wordt onderbroken. Inspecteer daarom altijd een gifbericht voordat u het bericht uit de wachtrij verwijdert. Als u de inhoud van het bericht wilt zien, start u een transactie, ontvangt u de hoofdtekst van het bericht, geeft u de berichttekst weer en rolt u de transactie terug. Totdat u positief bent dat het betreffende bericht een gifbericht is, is het belangrijk om de transactie terug te draaien.

Voorbeeld

In het volgende voorbeeld ziet u hoe u een bericht veilig kunt inspecteren voor de gespreksafhandeling e29059bb-9922-40f4-a575-66b2e4c70cf9 in de wachtrij ExpenseQueue.> [! OPMERKING]
> De codevoorbeelden in dit artikel zijn getest met behulp van de AdventureWorks2025 voorbeelddatabase, die u kunt downloaden van de Microsoft SQL Server-voorbeelden en communityprojecten startpagina.

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 AS VARBINARY (MAX),
    @validation AS 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

Wanneer je een gifbericht vindt, beëindig je het gesprek. In het volgende voorbeeld wordt het gesprek e29059bb-9922-40f4-a575-66b2e4c70cf9 beëindigd:

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

Wanneer een gesprek eindigt, verwijdert Service Broker de berichten voor dat gesprek. De toepassing die normaal gesproken het bericht verwerkt, ontvangt geen EndDialog - of Foutbericht voor dit gesprek. Als de toepassing de status onderhoudt, moet u daarom voorzichtig zijn met het verwijderen van de status die aan het gesprek is gekoppeld nadat het gesprek met een fout is beëindigd.

Als een service een bericht niet kan verwerken, betekent dit dat de service de taak voor het gesprek niet kan voltooien. Als u het gesprek beëindigt met een fout, wordt de andere deelnemer in het gesprek op de hoogte gesteld dat de taak is mislukt.