Esquema de la aplicación de Service Broker

La mayoría de las aplicaciones de Service Broker siguen los mismos pasos básicos para recibir y procesar los mensajes:

  1. La aplicación comienza una transacción.

  2. Si la aplicación mantiene el estado, la aplicación obtiene un identificador de grupo de conversación. La aplicación utiliza este identificador para restaurar el estado a partir de una tabla de estados. Si no hay ningún grupo de conversación con mensajes que estén listos para recibirse, la aplicación revierte la transacción y finaliza.

  3. La aplicación recibe al menos un mensaje de la cola. Si la aplicación tiene un identificador de grupo de conversación, la aplicación utiliza el identificador del grupo de conversación para recibir los mensajes para ese grupo de conversación. Si no hay más mensaje disponibles para recibirse, la aplicación confirma la transacción y vuelve al paso 1.

  4. La aplicación valida el contenido de los mensajes basándose en el nombre del tipo de mensaje.

  5. La aplicación procesa los mensajes basándose en el nombre del tipo de mensaje y el contenido del mensaje.

  6. La aplicación envía cualquier mensaje que resulte del procesamiento.

  7. Si la aplicación mantiene el estado, la aplicación actualiza la tabla de estados utilizando el identificador del grupo de conversación como clave principal de la tabla.

  8. La aplicación vuelve al paso 3 para comprobar si más mensajes están disponibles.

La estructura precisa de la aplicación depende de los requisitos de la aplicación, el estilo de comunicación de la aplicación, de si la aplicación es un servicio de destino o un servicio iniciador y de si Service Broker activa la aplicación o no.

Por ejemplo, una aplicación iniciadora envía un mensaje antes de iniciar el bucle de procesamiento que se describe en los pasos anteriores. El servicio iniciador puede enviar un mensaje desde otro programa o procedimiento almacenado y, a continuación, utilizar un procedimiento almacenado de activación para la cola del servicio iniciador. Por ejemplo, una aplicación de entrada de pedidos puede incluir una aplicación externa que inicie la conversación para introducir el pedido. Una vez insertado el pedido, la aplicación externa no necesita seguir ejecutándose. Un procedimiento almacenado de activación para el servicio iniciador envía la confirmación del pedido cuando vuelve una respuesta del servicio de pedidos. El procedimiento almacenado de activación también procesa cualquier mensaje de error de Service Broker que sea devuelto por el servicio de destino y envía notificaciones de que el pedido no se ha podido confirmar.

Alternativamente, en lugar de enviar un mensaje desde un programa diferente, la aplicación iniciadora puede enviar un mensaje y, a continuación, iniciar el bucle de procesamiento como parte del mismo programa. Independientemente de estas variaciones, el esquema básico sigue siendo el mismo.

Una aplicación que procesa un número grande de mensajes en el mismo grupo de conversación puede mantener un recuento de mensajes recibidos y confirmar una transacción después de procesar cierto número de mensajes. Esta estrategia de recuento y confirmación permite a la aplicación mantener transacciones relativamente cortas y permite que la aplicación procese grupos de conversación diferentes.

Ejemplo

El ejemplo Transact-SQL siguiente procesa todos los mensajes en la cola MyServiceQueue. El procesamiento para el mensaje es mínimo. Si el mensaje es EndDialog o un mensaje de error, el código finaliza la conversación. Para cualquier otro mensaje, el código crea una representación XML del mensaje y genera un conjunto de resultados que contiene el identificador de conversación, el nombre del tipo de mensaje y el XML. Si no hay ningún mensaje disponible durante 500 milisegundos, el código finaliza.

Para mayor simplicidad, el script genera un conjunto de resultados para cada mensaje. Si un error se produce leyendo la cola, el script confirma los cambios sin generar ningún resultado. Por consiguiente, este script quitará silenciosamente cualquier mensaje que produzca un error.

Nota

Dado que el script solamente muestra los mensajes, no es posible ningún mensaje dudoso para este script. Por consiguiente, el script no contiene el código para tratar los mensajes dudosos. Deberá escribirse una aplicación de producción para administrar los mensajes dudosos. Para obtener más información sobre los mensajes dudosos, vea Controlar mensajes dudosos.

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.