Los mensajes transaccionales son un tipo de mensaje especial proporcionado por ApsaraMQ for RocketMQ que garantiza que tanto la transacción local como la entrega del mensaje se completen correctamente o fallen en conjunto. Este mecanismo de confirmación en dos fases mantiene sincronizado el servicio principal con sus consumidores posteriores, sin la sobrecarga de bloqueo de recursos que implican las transacciones distribuidas de arquitectura extendida (XA).

Utilice mensajes transaccionales cuando:
Un sistema de pedidos deba actualizar su base de datos y notificar a los servicios de logística, puntos y carrito de forma atómica.
Un servicio de pagos deba registrar un débito y publicar un evento para los consumidores de libros contables posteriores.
La entrega de un mensaje sin completar la transacción local (o viceversa) dejaría al sistema en un estado inconsistente.
Funcionamiento de los mensajes transaccionales
Limitaciones de los mensajes normales
Combinar una transacción local de base de datos con el envío de un mensaje normal crea una brecha donde una operación puede completarse sin la otra:
El mensaje se envía, pero la transacción local falla. Los consumidores posteriores actúan sobre un cambio no confirmado.
La transacción local se confirma, pero el envío del mensaje falla. Los consumidores posteriores nunca se enteran del cambio.
Se produce un tiempo de espera agotado y ni el productor ni el broker pueden determinar si deben confirmar o revertir la operación.

Costo elevado de las transacciones XA
El protocolo XA coordina transacciones distribuidas entre sistemas, pero bloquea los recursos durante toda la duración de la transacción. A medida que aumenta el número de sistemas participantes, se incrementa la contención por bloqueos y disminuye el rendimiento.
Confirmación en dos fases con mensajes parciales
Los mensajes transaccionales de ApsaraMQ for RocketMQ utilizan un protocolo de confirmación en dos fases que evita ambos problemas:

Envío de un mensaje parcial. El productor envía un mensaje al broker. El broker lo almacena y devuelve una confirmación (ACK) al productor. El mensaje se marca como no listo para entrega; un mensaje en este estado se denomina mensaje parcial. Los consumidores posteriores aún no pueden verlo.
Ejecución de la transacción local. El productor ejecuta su operación local en la base de datos (por ejemplo, actualizar el estado de un pedido de no pagado a pagado).
-
Confirmación o reversión. El productor reporta el resultado de la transacción local al broker:
Confirmación: El broker marca el mensaje parcial como listo para entrega y lo envía a los consumidores.
Reversión: El broker descarta el mensaje parcial. Los consumidores nunca lo reciben.
Verificación del estado de la transacción (recuperación). Si el broker no recibe un resultado de confirmación o reversión debido a un fallo de red o al reinicio del productor, envía una consulta de estado a una instancia del productor en el clúster. El productor comprueba el resultado de la transacción local y lo reporta nuevamente al broker.

Para consultar el intervalo de consulta y el número máximo de reintentos, consulte Parameter limits.
Ciclo de vida del mensaje
Un mensaje transaccional pasa por los siguientes estados:

|
Estado |
Descripción |
|
Inicialización |
El productor construye el mensaje parcial y se prepara para enviarlo al broker. |
|
Transacción pendiente de confirmación |
El broker almacena el mensaje parcial en el sistema de almacenamiento de transacciones. A diferencia de un mensaje normal, el broker no persiste el mensaje parcial de la manera estándar. El mensaje es invisible para los consumidores. |
|
Confirmado para consumo |
La transacción local se completa correctamente. El broker almacena el mensaje parcial en el sistema de almacenamiento y lo hace visible para los consumidores. |
|
Reversión del mensaje |
La transacción local falla. El broker descarta el mensaje parcial. El flujo de trabajo finaliza. |
|
En proceso de consumo |
Un consumidor recoge el mensaje y comienza a procesarlo. Si el consumidor no devuelve un resultado dentro del tiempo de espera configurado, ApsaraMQ for RocketMQ reintenta la entrega. Para más detalles, consulte Consumption retry. |
|
Confirmación del resultado de consumo |
El consumidor confirma el resultado del consumo. El mensaje se marca como consumido, pero no se elimina de inmediato. |
|
Eliminación del mensaje |
El período de retención del mensaje caduca o el espacio de almacenamiento se agota. ApsaraMQ for RocketMQ elimina los mensajes más antiguos de forma rotativa. Consulte Message storage and cleanup. |
De forma predeterminada, ApsaraMQ for RocketMQ retiene todos los mensajes. Un mensaje consumido no se elimina inmediatamente; los consumidores pueden volver a consumirlo hasta que expire el período de retención o se libere espacio de almacenamiento.
Envío de mensajes transaccionales (Java)
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Un tema con
MessageTypeestablecido enTransactionen la consola de ApsaraMQ for RocketMQ.El endpoint de la instancia (disponible en la pestaña Endpoints de la página Instance Details)
(Si aplica) El nombre de usuario y la contraseña de la instancia (disponibles en la pestaña Intelligent Authentication de la página Access Control)
Diferencias respecto a los mensajes normales
El envío de un mensaje transaccional difiere del envío de un mensaje normal en dos aspectos:
Se requiere un verificador de transacciones. Registre un verificador de transacciones al construir el productor. El verificador se ejecuta automáticamente si el broker consulta el estado de la transacción tras un fallo.
Se requiere vinculación del tema. Vincule el tema destino al productor durante la construcción para que el verificador integrado pueda recuperar el estado de la transacción.
Código de ejemplo
Construya un productor con un verificador de transacciones, inicie una transacción, envíe un mensaje parcial, ejecute la transacción local y luego confirme o revierta la operación.
Código de ejemplo
Reemplace los siguientes marcadores de posición con sus valores reales:
|
Marcador de posición |
Descripción |
Ejemplo |
|
|
Endpoint de la instancia (disponible en la pestaña Endpoints de la página Instance Details) |
|
|
|
Nombre del tema con |
|
|
|
Nombre de usuario de la instancia (disponible en la pestaña Intelligent Authentication de la página Access Control) |
|
|
|
Contraseña de la instancia |
|
Para consultar ejemplos completos del SDK en todos los idiomas compatibles, consulte Apache RocketMQ 5.x SDKs.
Mejores prácticas
Minimizar resultados de transacción desconocidos
La verificación del estado de la transacción funciona como una red de seguridad ante fallos durante la confirmación o reversión. Un alto volumen de verificaciones de estado degrada el rendimiento del sistema y retrasa la entrega de mensajes. Diseñe las transacciones locales para que devuelvan un resultado definitivo de confirmación o reversión lo antes posible.
Gestión correcta de transacciones en curso
Cuando el broker consulta el estado de un mensaje parcial y la transacción local aún se está ejecutando, devuelva Unknown en lugar de Commit o Rollback. Devolver un resultado prematuro puede causar inconsistencia en los datos.
Si las verificaciones de estado llegan demasiado pronto porque la transacción local es lenta, considere los siguientes enfoques:
Aumentar el retraso de la primera verificación. Configure un intervalo más largo antes de que el broker envíe su primera consulta de estado. Compensación: esto también retrasa la recuperación en caso de transacciones que realmente hayan fallado.
Detectar explícitamente el estado en curso. Diseñe la lógica de la transacción local para distinguir entre "en ejecución" y "fallida", de modo que el verificador devuelva el estado correcto.
Límites
|
Restricción |
Detalles |
|
Tipo de tema |
Los mensajes transaccionales requieren un tema con |
|
Un SendReceipt por transacción |
Cada transacción admite únicamente un |
|
Solo consistencia eventual |
Los mensajes transaccionales garantizan la consistencia entre la transacción local y la entrega del mensaje. No garantizan consistencia en tiempo real entre los consumidores posteriores. Hasta que se entregue el mensaje, el estado posterior puede ir a la zaga de la transacción anterior. Utilice mensajes transaccionales solo cuando sea aceptable el procesamiento asíncrono posterior. |
|
Responsabilidad del lado del consumidor |
ApsaraMQ for RocketMQ garantiza la entrega de los mensajes confirmados, pero cada consumidor posterior debe gestionar correctamente el procesamiento. Implemente lógica de reintento de consumo para manejar fallos transitorios. Consulte Consumption retry. |
|
Tiempo de espera de la transacción |
Si el broker no puede determinar el resultado de la transacción después del tiempo de espera configurado y el número máximo de reintentos, revierte el mensaje parcial de forma predeterminada. Consulte Parameter limits. |