Conceitos
Saga pattern / compensating transactions
Intuição
Pense em planejar uma viagem: você reserva o voo, depois o hotel, depois o carro, cada reserva confirmada separadamente em vez de tudo travado numa única transação gigante que só libera no final. Se o carro não tem mais vaga, você não desfaz o tempo — você cancela o voo e o hotel que já tinha reservado, um a um, como ações de "conserto" específicas para cada reserva. O resultado final é o mesmo de nunca ter reservado nada, mas chegou lá por um caminho de correções, não de um rebobinar mágico.
Como funciona
Uma saga reescreve uma transação longa (long-lived transaction) como uma sequência de subtransações menores, cada uma curta o bastante para comitar e liberar seus próprios locks rapidamente, podendo ser intercalada no tempo com outras transações do sistema. Para cada subtransação é definida de antemão uma transação compensatória correspondente. Se todas as subtransações terminam com sucesso, a saga como um todo é considerada concluída; se uma delas falha no meio do caminho, o sistema executa as compensações das subtransações já concluídas em ordem inversa — o que o paper chama de recuperação para trás, desfazendo o efeito prático do trabalho já commitado. Um ponto central: compensar uma subtransação não significa restaurar o banco ao exato estado anterior a ela, e sim uma aproximação aceitável desse estado do ponto de vista da aplicação, já que outras transações concorrentes podem ter tocado os mesmos dados nesse meio-tempo. Essa é exatamente a garantia que a saga sacrifica em troca disso: isolamento total. Como cada subtransação libera seus locks assim que termina, em vez de segurar tudo bloqueado até o fim do processo inteiro, outras transações podem enxergar e até modificar resultados intermediários da saga ainda em andamento — algo impossível numa transação ACID tradicional. O que a saga preserva é uma forma de atomicidade observável: o processo termina, do ponto de vista de fora, equivalente a ter sido totalmente concluído ou a nunca ter acontecido.
Na prática
Esse trade-off — abrir mão de isolamento completo para evitar segurar locks por muito tempo — é o que torna sagas viáveis tanto dentro de um único banco de dados quanto, décadas depois, como padrão de coordenação de processos de negócio que atravessam múltiplos serviços independentes, cada um com seu próprio armazenamento, onde nenhum gerenciador de transações central consegue fazer um commit distribuído. Em troca, quem projeta a saga assume a responsabilidade extra de definir com cuidado uma compensação para cada passo, capaz de lidar com o fato de que os dados podem ter mudado desde que aquele passo rodou.
Use em um desenho
Pratique na escola de System Design os casos que dependem deste conceito.