Condividi tramite


Struttura delle applicazioni di Service Broker

La maggior parte delle applicazioni di Service Broker seguono gli stessi passaggi di base per ricevere ed elaborare messaggi:

  1. Avvio di una transazione.

  2. Se mantiene informazioni sullo stato, l'applicazione ottiene un identificatore del gruppo di conversazioni e lo utilizza per ripristinare lo stato da una tabella di stato. Se non è presente alcun gruppo di conversazioni con messaggi pronti per essere ricevuti, viene eseguito il rollback della transazione, quindi si esce dall'applicazione.

  3. Ricezione di uno o più messaggi dalla coda. Se l'applicazione dispone di un identificatore del gruppo di conversazioni, lo utilizza per ricevere i messaggi da tale gruppo di conversazioni. Se non è disponibile alcun messaggio per la ricezione, l'applicazione esegue il commit della transazione e ritorna al passaggio 1.

  4. Convalida del contenuto dei messaggi in base al nome del tipo di messaggio.

  5. Elaborazione dei messaggi in base al nome del tipo di messaggio e al contenuto del messaggio.

  6. Invio di tutti i messaggi risultanti dall'elaborazione.

  7. Se mantiene informazioni sullo stato, l'applicazione aggiorna la tabella di stato tramite l'identificatore del gruppo di conversazioni come chiave primaria per la tabella.

  8. Ritorno al passaggio 3 per controllare se sono disponibili ulteriori messaggi.

La struttura esatta dell'applicazione dipende dai requisiti e dallo stile di comunicazione dell'applicazione stessa, dal fatto che l'applicazione sia un servizio di origine o di destinazione e dal fatto che l'applicazione venga attivata da Service Broker o meno.

Si supponga ad esempio che un'applicazione di origine invii un messaggio prima di avviare il ciclo di elaborazione descritto nei passaggi precedenti. Il servizio di origine può inviare un messaggio da un altro programma o stored procedure, quindi utilizzare una stored procedure di attivazione per la coda del servizio di origine. Un'applicazione per la registrazione di ordini può includere ad esempio un'applicazione esterna che avvia la conversazione per immettere l'ordine. Dopo l'immissione dell'ordine, l'applicazione esterna non deve rimanere in esecuzione. Una stored procedure di attivazione per il servizio di origine invia la conferma dell'ordine quando viene restituita una risposta dal servizio relativo all'ordine. La stored procedure di attivazione elabora inoltre tutti i messaggi di errore di Service Broker restituiti dal servizio di destinazione e invia notifiche relative all'impossibilità di confermare l'ordine.

In alternativa, anziché inviare un messaggio da un programma diverso, l'applicazione di origine può inviare un messaggio, quindi avviare il ciclo di elaborazione come parte dello stesso programma. Indipendentemente da queste variazioni, la struttura di base rimane la stessa.

Un'applicazione che elabora un numero elevato di messaggi nello stesso gruppo di conversazioni può tenere conto dei messaggi ricevuti e può eseguire il commit di una transazione dopo avere elaborato un numero di messaggi specifico. Questa strategia che prevede l'esecuzione di un conteggio e del commit consente all'applicazione di mantenere transazioni relativamente brevi e di elaborare gruppi di conversazioni diversi.

Esempio

Nell'esempio Transact-SQL seguente vengono elaborati tutti i messaggi presenti nella coda MyServiceQueue. L'elaborazione per il messaggio è minima. Se il messaggio è un messaggio EndDialog o Error, la conversazione viene terminata. Per qualsiasi altro messaggio, nel codice viene creata una rappresentazione XML del messaggio e viene prodotto un set di risultati che contiene l'handle di conversazione, il nome del tipo di messaggio e il codice XML. Quando non è disponibile alcun messaggio per 500 millisecondi, si esce dal codice.

Per semplicità, lo script produce un set di risultati per ogni messaggio. Se si verifica un errore durante la lettura dalla coda, lo script esegue il commit delle modifiche senza produrre alcun risultato. Di conseguenza questo script rimuoverà automaticamente qualsiasi messaggio che provoca un errore.

Nota

Poiché nello script i messaggi vengono semplicemente visualizzati, non è possibile che siano presenti messaggi non elaborabili. Di conseguenza lo script non contiene codice per la gestione di messaggi non elaborabili, mentre un'applicazione in ambiente di produzione deve essere scritta per gestire anche messaggi non elaborabili. Per ulteriori informazioni sui messaggi non elaborabili, vedere Gestione di messaggi non elaborabili.

USE AdventureWorks2008R2 ;
GO

-- Process all conversation groups.

WHILE (1 = 1)
BEGIN

DECLARE @conversation_handle UNIQUEIDENTIFIER,
        @conversation_group_id UNIQUEIDENTIFIER,
        @message_body XML,
        @message_type_name NVARCHAR(128);


-- Begin a transaction, one per conversation group.

BEGIN TRANSACTION ;

-- Get next conversation group.

WAITFOR(
   GET CONVERSATION GROUP @conversation_group_id FROM MyServiceQueue),
   TIMEOUT 500 ;

-- Restore the state for this conversation group here

-- If there are no more conversation groups, break.

IF @conversation_group_id IS NULL
BEGIN
    ROLLBACK TRANSACTION ;
    BREAK ;
END ;

    -- Process all messages in the conversation group.

    WHILE 1 = 1
    BEGIN

        -- Get the next message.

        RECEIVE
           TOP(1)
           @conversation_handle = conversation_handle,
           @message_type_name = message_type_name,
           @message_body =
           CASE
              WHEN validation = 'X' THEN CAST(message_body AS XML)
              ELSE CAST(N'<none/>' AS XML)
          END
       FROM MyServiceQueue
       WHERE conversation_group_id = @conversation_group_id;

       -- If there is no message, or there is an error
       -- reading from the queue, break.

       IF @@ROWCOUNT = 0 OR @@ERROR <> 0
           BREAK;

       -- Process the message. In this case, the program ends the conversation
       -- for Error and EndDialog messages. For all other messages, the program
       -- produces a result set with information about the message.

       SELECT @conversation_handle,
              @message_type_name,
              @message_body ;

       -- If the message is an end dialog message or an error,
       -- end the conversation. Notice that other conversations
       -- in the same conversation group may still have messages
       -- to process. Therefore, the program does not break after
       -- ending the conversation.

       IF @message_type_name =
              'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
          OR @message_type_name =
              'https://schemas.microsoft.com/SQL/ServiceBroker/Error'
       BEGIN
          END CONVERSATION @conversation_handle ;
       END ;

    END ; -- Process all messages in conversation group.

   COMMIT TRANSACTION ;

END ; -- Process all conversation groups.