Condividi tramite


Rimozione di messaggi non elaborabili

Un messaggio non elaborabile è un messaggio contenente informazioni che un'applicazione non è in grado di elaborare correttamente. Può accadere, ad esempio, che una workstation di produzione invii una richiesta per il ritiro di un articolo dalle scorte di magazzino subito prima che un ordine di modifica renda obsoleto l'articolo. L'ordine di modifica diventa effettivo mentre la richiesta è in fase di inoltro. L'applicazione di gestione delle scorte riceve la richiesta dalla workstation ma non è in grado di elaborarla. L'operazione sul database per l'aggiornamento del numero di articoli in magazzino non è possibile. Viene quindi eseguito il rollback della transazione contenente l'operazione di ricezione e il messaggio viene reinserito nella coda. In questa situazione l'applicazione continua a ricevere lo stesso messaggio, l'aggiornamento non è mai possibile e il messaggio ritorna nella coda.

Un messaggio non elaborabile non contiene dati danneggiati e non rappresenta necessariamente una richiesta non valida. I controlli dell'identità dei messaggi eseguiti da Service Broker consentono di rilevare i messaggi contenenti dati danneggiati. Le applicazioni inoltre eseguono di solito la convalida del contenuto dei messaggi ed eliminano quelli contenenti richieste non valide. Al contrario, molti messaggi non elaborabili sono validi al momento della creazione ma in seguito non è possibile elaborarli.

Rilevamento automatico dei messaggi non elaborabili

Service Broker esegue il rilevamento automatico dei messaggi non elaborabili. Quando viene eseguito per cinque volte il rollback di una transazione contenente l'istruzione RECEIVE, tutte le code da cui la transazione ha ricevuto i messaggi vengono disattivate automaticamente mediante l'impostazione automatica dello stato della coda su OFF e viene generato un evento di tipo Broker:Queue Disabled.

Per ricevere una notifica quando una coda viene disattivata, l'amministratore può utilizzare gli avvisi di SQL Server Agent. È inoltre possibile sviluppare un'applicazione per consentire a Service Broker di rilevare la disattivazione delle code e controllare spesso la coda allo scopo di verificare la presenza di messaggi non elaborabili. Dopo aver determinato i messaggi che non è possibile elaborare, l'applicazione imposta lo stato della coda su ON e termina la conversazione a cui il messaggio appartiene con un errore. L'eliminazione dello stato associato a una conversazione quando questa viene terminata deve essere eseguita con precauzione da parte dell'applicazione che rileva i messaggi non elaborabili. Per ulteriori informazioni sulla creazione di un'applicazione per il recupero a seguito di messaggi non elaborabili, vedere Handling Poison Messages.

Rimozione di messaggi non elaborabili a livello amministrativo

La maggior parte delle applicazioni dovrebbe rilevare e rimuovere i messaggi non elaborabili a livello di programmazione, tuttavia in alcuni casi può essere necessario eseguire questa operazione manualmente. La parte dell'applicazione che esegue il recupero, ad esempio, potrebbe non essere in grado di rilevare un messaggio non elaborabile o di eliminare in modo sicuro lo stato salvato della conversazione.

La rimozione manuale di un messaggio comporta il rischio di interrompere una conversazione importante. È quindi sempre consigliabile controllare un messaggio non elaborabile prima di rimuoverlo dalla coda. Per visualizzare il contenuto del messaggio, iniziare una transazione, ricevere e visualizzare il corpo del messaggio e quindi eseguire il rollback della transazione. Finché non si ha la certezza che si tratti di un messaggio non elaborabile è importante eseguire il rollback della transazione.

Esempio

Nell'esempio seguente viene illustrato come controllare in modo sicuro un messaggio mediante l'handle di conversazione e29059bb-9922-40f4-a575-66b2e4c70cf9 nella coda ExpenseQueue.

use AdventureWorks ;
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 ;

  -- Rollback 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 viene trovato un messaggio non elaborabile, la conversazione viene terminata. Nell'esempio seguente viene terminata la conversazione 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 una conversazione viene terminata, Service Broker elimina i messaggi relativi alla conversazione. Si noti che l'applicazione che elabora normalmente il messaggio non riceve un messaggio EndDialog o Error per questa conversazione. Pertanto, se l'applicazione mantiene lo stato è necessario terminare la conversazione con un errore e quindi rimuovere con precauzione lo stato associato alla conversazione stessa.

Se un servizio non è in grado di elaborare un messaggio, non può completare l'attività per la conversazione. Quando una conversazione viene terminata con un errore, gli altri partecipanti ricevono la notifica che non è possibile completare l'attività.

Vedere anche

Concetti

Esecuzione di query sulle code

Altre risorse

RECEIVE (Transact-SQL)
END CONVERSATION (Transact-SQL)

Guida in linea e informazioni

Assistenza su SQL Server 2005