As mensagens transacionais são um tipo de mensagem especial do ApsaraMQ for RocketMQ que garante o sucesso ou a falha simultânea da transação local e da entrega da mensagem. Esse mecanismo de commit em duas fases mantém a sincronia entre o serviço principal e seus consumidores downstream, sem a sobrecarga de bloqueio de recursos das transações distribuídas da eXtended Architecture (XA).

Use mensagens transacionais quando:
Um sistema de pedidos precisar atualizar o banco de dados e notificar os serviços de logística, pontos e carrinho de forma atômica.
Um serviço de pagamento precisar registrar um débito e publicar um evento para consumidores downstream do livro-razão.
A entrega de uma mensagem sem a conclusão da transação local (ou vice-versa) deixar o sistema em um estado inconsistente.
Como funcionam as mensagens transacionais
Limitações das mensagens normais
Combinar uma transação local no banco de dados com o envio de uma mensagem normal cria uma lacuna em que uma operação pode ter sucesso enquanto a outra falha:
A mensagem é enviada, mas a transação local falha. Os consumidores downstream agem sobre uma alteração não confirmada.
A transação local é confirmada, mas o envio da mensagem falha. Os consumidores downstream nunca recebem a notificação sobre a alteração.
Ocorre um timeout e nem o produtor nem o broker conseguem determinar se devem confirmar ou reverter a operação.

Alto custo das transações XA
O protocolo XA coordena transações distribuídas entre sistemas, mas bloqueia recursos durante toda a duração da transação. À medida que o número de sistemas participantes aumenta, a contenção de bloqueios cresce e o throughput diminui.
Commit em duas fases com half messages
As mensagens transacionais do ApsaraMQ for RocketMQ usam um protocolo de commit em duas fases que evita ambos os problemas:

Envie uma half message. O produtor envia uma mensagem ao broker. O broker a persiste e retorna um reconhecimento (ACK) ao produtor. A mensagem é marcada como não pronta para entrega — uma mensagem nesse estado é chamada de half message. Os consumidores downstream ainda não podem vê-la.
Execute a transação local. O produtor executa sua operação local no banco de dados (por exemplo, atualizar o status de um pedido de não pago para pago).
-
Confirme ou reverta. O produtor informa o resultado da transação local ao broker:
Commit: O broker marca a half message como pronta para entrega e a encaminha aos consumidores.
Rollback: O broker descarta a half message. Os consumidores nunca a recebem.
Verificação de status da transação (recuperação). Caso o broker não receba um resultado de commit ou rollback — devido a uma falha de rede ou reinicialização do produtor —, ele envia uma consulta de status a uma instância do produtor no cluster. O produtor verifica o resultado da transação local e o reenvia ao broker.

Para obter informações sobre o intervalo de consulta e a contagem máxima de tentativas, consulte Limites de parâmetros.
Ciclo de vida da mensagem
Uma mensagem transacional passa pelos seguintes estados:

|
Estado |
Descrição |
|
Inicialização |
O produtor constrói a half message e prepara-se para enviá-la ao broker. |
|
Transação pendente de commit |
O broker armazena a half message no sistema de armazenamento de transações. Diferentemente de uma mensagem normal, o broker não persiste a half message da maneira padrão. A mensagem permanece invisível para os consumidores. |
|
Confirmada para consumo |
A transação local é bem-sucedida. O broker armazena a half message no sistema de armazenamento, tornando-a visível para os consumidores. |
|
Rollback da mensagem |
A transação local falha. O broker descarta a half message. O fluxo de trabalho é encerrado. |
|
Em consumo |
Um consumidor recebe a mensagem e inicia seu processamento. Se o consumidor não retornar um resultado dentro do timeout configurado, o ApsaraMQ for RocketMQ tenta entregar a mensagem novamente. Para mais detalhes, consulte Tentativa de consumo. |
|
Commit do resultado de consumo |
O consumidor confirma o resultado do consumo. A mensagem é marcada como consumida, mas não é excluída imediatamente. |
|
Exclusão da mensagem |
O período de retenção da mensagem expira ou o espaço de armazenamento fica escasso. O ApsaraMQ for RocketMQ exclui as mensagens mais antigas de forma rotativa. Consulte Armazenamento e limpeza de mensagens. |
Por padrão, o ApsaraMQ for RocketMQ retém todas as mensagens. Uma mensagem consumida não é excluída imediatamente — os consumidores podem consumi-la novamente até que o período de retenção expire ou o espaço de armazenamento seja recuperado.
Enviar mensagens transacionais (Java)
Pré-requisitos
Antes de começar, certifique-se de ter:
Um tópico com
MessageTypedefinido comoTransactionno console do ApsaraMQ for RocketMQ.O endpoint da instância (na aba Endpoints da página Instance Details)
(Se aplicável) O nome de usuário e a senha da instância (na aba Intelligent Authentication da página Access Control)
Diferenças em relação às mensagens normais
O envio de uma mensagem transacional difere do envio de uma mensagem normal em dois aspectos:
Verificador de transação obrigatório. Registre um verificador de transação ao construir o produtor. O verificador é executado automaticamente se o broker consultar o status da transação após uma falha.
Vinculação de tópico obrigatória. Vincule o tópico de destino ao produtor durante a construção para que o verificador integrado possa recuperar o status da transação.
Código de exemplo
Construa um produtor com um verificador de transação, inicie uma transação, envie uma half message, execute a transação local e, em seguida, confirme ou reverta a operação.
Código de exemplo
Substitua os seguintes placeholders pelos valores reais:
|
Placeholder |
Descrição |
Exemplo |
|
|
Endpoint da instância (na aba Endpoints da página Instance Details) |
|
|
|
Nome do tópico com |
|
|
|
Nome de usuário da instância (na aba Intelligent Authentication da página Access Control) |
|
|
|
Senha da instância |
|
Para exemplos completos de SDK em todas as linguagens suportadas, consulte SDKs do Apache RocketMQ 5.x.
Melhores práticas
Minimize resultados de transação desconhecidos
A verificação de status da transação funciona como uma rede de segurança para falhas durante o commit ou rollback. Um alto volume de verificações de status degrada o desempenho do sistema e atrasa a entrega de mensagens. Projete transações locais para retornar um resultado definitivo de Commit ou Rollback o mais rápido possível.
Trate corretamente as transações em andamento
Quando o broker consulta o status de uma half message e a transação local ainda está em execução, retorne Unknown — e não Commit ou Rollback. Retornar um resultado prematuro pode causar inconsistência de dados.
Se as verificações de status chegarem cedo demais porque a transação local é lenta, considere estas abordagens:
Aumente o atraso da primeira verificação. Configure um intervalo maior antes de o broker enviar sua primeira consulta de status. Contrapartida: isso também atrasa a recuperação para transações que realmente falharam.
Detecte explicitamente o estado em andamento. Projete a lógica da transação local para distinguir entre "ainda em execução" e "falhou", para que o verificador retorne o status correto.
Limites
|
Restrição |
Detalhes |
|
Tipo de tópico |
Mensagens transacionais exigem um tópico com |
|
Um SendReceipt por transação |
Cada transação suporta apenas um |
|
Apenas consistência eventual |
As mensagens transacionais garantem a consistência entre a transação local e a entrega da mensagem. Elas não garantem consistência em tempo real entre os consumidores downstream. Até que a mensagem seja entregue, o estado downstream pode ficar defasado em relação à transação upstream. Use mensagens transacionais apenas quando o processamento assíncrono downstream for aceitável. |
|
Responsabilidade do lado do consumidor |
O ApsaraMQ for RocketMQ garante a entrega das mensagens confirmadas, mas cada consumidor downstream deve lidar corretamente com o processamento. Implemente uma lógica de tentativa de consumo para lidar com falhas transitórias. Consulte Tentativa de consumo. |
|
Timeout da transação |
Se o broker não conseguir determinar o resultado da transação após o timeout configurado e a contagem máxima de tentativas, ele reverte a half message por padrão. Consulte Limites de parâmetros. |