2

Provocação: o transactional outbox realmente resolve o dual write ou só passa o problema pra outro lugar?

No produtor, blz: dado + outbox ficam na mesma transação.

Mas no consumidor o exemplo faz AplicarEfeitoDeNegocioAsync() + gravação da inbox. Isso só é atomicamente seguro se esse "efeito" estiver no mesmo banco/transação. Se ali dentro tiver uma chamada para outra API, pagamento, e-mail, outro broker ou qualquer outra coisa, o dual write nasceu de novo, agora entre esse consumidor e o sistema externo.

Nesse caso, até a afirmação de que "Outbox + Inbox entrega consistência ponta a ponta" merece um asterisco enorme.

No fim, me parece que Outbox não elimina o problema de consistência distribuída, ele transforma uma operação impossível de tornar atômica em uma sequência de operações locais idempotentes na verdade.

Carregando publicação patrocinada...
1

Oi, Tiago! Obrigado pela provocação e pela leitura cuidadosa. Você está acertando no ponto mais importante: o Transactional Outbox resolve o dual write entre a transação local e a publicação do evento, mas não cria uma transação distribuída entre o banco da aplicação e qualquer sistema externo que o consumidor toque depois.

A sua crítica está certa quando você aponta que, se o efeito do consumidor for "chamar outra API, enviar e-mail, pagar, escrever em outro sistema ou disparar outro broker", aí o problema reaparece sob a forma de consistência externa. Nesse ponto, o Outbox não elimina o problema completo de consistência distribuída; ele o transforma em um problema de idempotência, retry e compensação.

Isso é um detalhe importante e eu acho que o artigo pode deixar isso mais explícito. O melhor jeito de formular é: o padrão elimina a inconsistência entre "persistir dado" e "publicar intenção de evento", mas não promete atomicidade entre o banco local e um sistema externo que atua depois. O que ele entrega, na prática, é consistência local + consistência eventual, com a garantia de que o evento não se perde e a de que o consumidor consegue reconhecer duplicatas.

Então eu concordo com o seu ponto: "Outbox + Inbox" não é magicamente "transação distribuída". Ele é uma disciplina de projeto para lidar com falhas temporárias, entrega at-least-once e idempotência. Em outras palavras, ele reduz o problema impossível de uma transação global para uma sequência de operações locais tratáveis.

Muito obrigado pela observação. Ela melhora o artigo e deixa a limitação correta do padrão bem mais clara para o leitor.