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
Un mensaje dudoso es un mensaje que contiene información que una aplicación no puede procesar correctamente. Por ejemplo, una estación de trabajo de fabricación podría enviar una solicitud para retirar una parte del inventario justo antes de que un pedido de cambio haga que la parte está obsoleta. La orden de cambio se activa mientras la solicitud de inventario está en tránsito. La aplicación de administración de inventario recibe la solicitud de la estación de trabajo, pero no puede procesar correctamente la solicitud y se produce un error en la operación de la base de datos para actualizar el número de piezas en existencias. La transacción que contiene la operación de recepción se revierte y devuelve el mensaje a la cola. En esta situación, la aplicación recibe el mismo mensaje, la actualización vuelve a generar un error y el mensaje vuelve a la cola.
Un mensaje dudoso no es un mensaje dañado y es posible que no sea una solicitud no válida. Service Broker contiene comprobaciones de integridad de mensajes que detectan mensajes incorrectos. También las aplicaciones suelen validar el contenido de un mensaje y descartan los que contienen una solicitud no permitida. Por otra parte, muchos mensajes dudosos eran válidos cuando se crearon pero, más tarde, se volvieron imposibles de procesar.
Detección automática de mensajes dudosos
Service Broker proporciona detección automática de mensajes dudosos. Cuando una transacción que contiene una RECEIVE instrucción revierte cinco veces, Service Broker deshabilita todas las colas desde las que la transacción recibió mensajes estableciendo automáticamente el estado de la cola en OFF. Además, Service Broker genera un evento de tipo Broker:Queue Disabled.
Un administrador puede usar alertas del Agente SQL Server para recibir notificaciones cuando se deshabilita una cola. Un programador también puede crear una aplicación que detecte cuándo Service Broker deshabilita una cola. Esta aplicación inspecciona a menudo los mensajes de la cola para encontrar el mensaje dudoso. Una vez que la aplicación determina qué mensaje no se puede procesar, establece el estado de la cola en ON y finaliza la conversación para el mensaje que tiene un error. Una aplicación que detecta mensajes dudosos debe limpiar cualquier estado asociado con la conversación cuando la finaliza. Para obtener más información sobre cómo crear una aplicación para recuperarse de mensajes dudosos, consulte Control de mensajes dudosos.
Eliminación de mensajes dudosos administrativamente
La mayoría de las aplicaciones deben realizar un seguimiento y eliminar mensajes dudosos mediante programación. Sin embargo, a veces puede ser necesario eliminar manualmente un mensaje envenenado. Por ejemplo, es posible que la parte de la aplicación que realiza la recuperación no pueda detectar el mensaje dudoso o que no pueda limpiar de forma segura el estado guardado de la conversación.
Si se quita un mensaje de forma manual se corre el riesgo de interrumpir una conversación importante. Por tanto, siempre debe inspeccionar un mensaje dudoso antes de quitarlo de la cola. Para ver el contenido del mensaje, inicie una transacción, reciba el cuerpo del mensaje, muestre el cuerpo del mensaje y, a continuación, revierta la transacción. Hasta que estés seguro de que el mensaje en cuestión se trate de un mensaje envenenado, es importante revertir la transacción.
Ejemplo
En el ejemplo siguiente se muestra cómo inspeccionar un mensaje de forma segura para el identificador de conversación e29059bb-9922-40f4-a575-66b2e4c70cf9 en la cola ExpenseQueue.> [NOTA]
> Los ejemplos de código de este artículo se probaron mediante la AdventureWorks2025 base de datos de ejemplo, que puede descargar desde la página principal ejemplos de Microsoft SQL Server y proyectos de comunidad .
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
Cuando encuentra un mensaje dudoso, finaliza la conversación. En el ejemplo siguiente se finaliza la conversación 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
Cuando una conversación finaliza, Service Broker descarta los mensajes de esa conversación. La aplicación que normalmente procesa el mensaje no recibe un endDialog o un mensaje de error para esta conversación. Por tanto, si la aplicación mantiene el estado, debe eliminar con cuidado el estado asociado con la conversación después de finalizar la conversación con un error.
Si un servicio no puede procesar un mensaje, significa que el servicio no puede completar la tarea de la conversación. Al finalizar la conversación con un error se notifica al otro participante de la conversación que la tarea ha generado un error.