O Padrão Transactional Outbox: Publicação Confiável de Eventos em Microserviços

O Padrão Transactional Outbox: Publicação Confiável de Eventos em Microserviços

Na arquitetura moderna de microserviços orientada a eventos (Event-Driven Architecture), os serviços emitem eventos como OrderCreated ou PaymentProcessed para comunicar alterações de estado de forma desacoplada.

No entanto, publicar eventos de forma totalmente confiável apresenta um desafio crítico: Como garantir que a atualização da base de dados e a publicação do evento ocorram juntas com sucesso ou falhem juntas?

Se um microserviço atualizar a base de dados local e depois tentar enviar uma mensagem via rede para um broker (como Apache Kafka ou RabbitMQ), falhas de rede podem corromper a integridade dos dados.

Para resolver este problema, os arquitetos de software utilizam o Padrão Transactional Outbox.


O Problema da Dupla Escrita (Dual-Write Problem)

Quando um microserviço tenta executar duas escritas separadas:

  1. Salvar os dados do negócio na base de dados local.
  2. Publicar o evento no Kafka.
Diagrama do problema de dupla escrita

Se a transação da base de dados for concluída com sucesso, mas a mensagem falhar no envio para o Kafka, os dados ficam salvos na base de dados, mas os serviços a jusante nunca são notificados. Resultado: Inconsistência de dados.


O que é o Padrão Transactional Outbox?

O padrão aproveita as transações locais ACID das bases de dados relacionais.

Em vez de enviar a mensagem diretamente pela rede, o serviço salva o evento numa tabela dedicada chamada Outbox Table dentro da mesma transação local que persiste os dados do negócio.

Devido às garantias ACID: Ambas as gravações são confirmadas juntas ou ambas são canceladas.

Um processo em segundo plano (Message Relay) lê periodicamente a tabela Outbox ou utiliza Change Data Capture (CDC) para transmitir os eventos ao broker.


Estratégias de Transmissão: Polling Publisher vs. CDC (Debezium)

Comparação entre Polling Publisher e Change Data Capture Debezium

1. Polling Publisher

Um processo em segundo plano consulta a tabela (SELECT * FROM outbox_events WHERE processed = FALSE), envia as mensagens para o Kafka e marca-as como processadas.

  • Vantagens: Simples de implementar.
  • Desvantagens: Latência adicional e carga de consultas na base de dados.

2. Change Data Capture (CDC com Debezium)

O Debezium lê diretamente os logs de transação da base de dados (PostgreSQL WAL) e envia as alterações instantaneamente para o Kafka.

  • Vantagens: Latência quase zero e sem impacto no desempenho da aplicação.
  • Desvantagens: Requer infraestrutura adicional (Kafka Connect).

Conclusão

O Padrão Transactional Outbox é essencial para garantir a consistência eventual e a resiliência em arquiteturas distribuídas de microserviços.