Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a:SQL Server
Azure SQL Managed Instance
La mayoría de las aplicaciones de Service Broker siguen los mismos pasos básicos para recibir y procesar los mensajes:
La aplicación comienza una transacción.
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 tiene mensajes que están listos para recibirse, la aplicación revierte la transacción y se cierra.
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.
La aplicación valida el contenido de los mensajes basándose en el nombre del tipo de mensaje.
La aplicación procesa los mensajes basándose en el nombre del tipo de mensaje y el contenido del mensaje.
La aplicación envía cualquier mensaje que resulte del procesamiento.
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.
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, usar un procedimiento almacenado de activación para la cola de servicio de inicio. Por ejemplo, una aplicación de entrada de pedido puede incluir una aplicación externa que inicia la conversación para escribir 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 los mensajes de error de Service Broker devueltos por el servicio de destino y envía notificaciones que el pedido no se pudo confirmar.
Como alternativa, en lugar de enviar un mensaje desde un programa diferente, la aplicación de inicio podría 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 gran número 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 un determinado 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.
Examples
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 lo tanto, el script no contiene código para controlar 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, consulte Control de mensajes dudosos.
Nota
Los ejemplos de código de este artículo se probaron mediante la base de datos de ejemplo AdventureWorks2025, que puede descargar de la página principal de ejemplos y proyectos de comunidad de Microsoft SQL Server .
USE [AdventureWorks2022];
GO
-- Process all conversation groups.
WHILE (1 = 1)
BEGIN
DECLARE @conversation_handle AS UNIQUEIDENTIFIER,
@conversation_group_id AS UNIQUEIDENTIFIER,
@message_body AS XML,
@message_type_name AS 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;
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.