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:
- Salvar os dados do negócio na base de dados local.
- Publicar o evento no Kafka.
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)
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.