Papers
Sagas
Hector Garcia-Molina, Kenneth Salem · ACM SIGMOD International Conference on Management of Data (SIGMOD) 1987, 1987
O problema: transações longas travando recursos do banco
O ponto de partida do paper é o que os autores chamam de transações longas (long-lived transactions, LLTs): operações que precisam manter locks sobre linhas ou tabelas do banco por um período relativamente extenso para preservar as propriedades clássicas de uma transação. O problema é que, enquanto essas transações longas seguram seus locks, transações curtas e muito mais comuns no mesmo sistema ficam bloqueadas esperando, o que degrada o desempenho geral do banco. Os autores observam algo aparentemente óbvio, mas com consequências importantes: uma sequência de transações curtas não é, por si só, uma transação atômica. Cada uma dessas transações individuais comita e libera seus próprios locks assim que termina, então não existe controle de concorrência tradicional (como bloqueio em duas fases) que trate a sequência inteira como uma única unidade indivisível sem voltar a segurar recursos pelo tempo todo — o que anula a vantagem de dividir o trabalho em pedaços menores. A motivação prática por trás disso são processos de negócio que naturalmente se estendem por várias etapas distintas, cada uma tocando partes diferentes do banco, e que não se encaixam bem nem no modelo de uma transação gigante bloqueante, nem no extremo oposto de simplesmente não ter garantia nenhuma sobre o resultado final do processo como um todo.
A ideia central: saga como sequência de subtransações com compensação
A proposta central do paper é a saga: uma transação longa reescrita como uma sequência de subtransações menores, cada uma curta o suficiente para comitar independentemente e liberar seus locks rapidamente, podendo ser intercalada no tempo com operações de outras transações do sistema. Para cada subtransação da saga, é definida de antemão uma transação compensatória correspondente. O sistema garante que, ou todas as subtransações da saga terminam com sucesso, ou, se uma delas falhar no meio do caminho, as transações compensatórias das subtransações já concluídas são executadas na ordem inversa, desfazendo o efeito prático do trabalho já commitado (o paper chama isso de recuperação para trás, em contraste com a recuperação para frente, que tenta seguir adiante até completar a saga). Um ponto sutil destacado pelos autores é que compensar uma subtransação não significa necessariamente devolver o banco ao exato estado que existia antes dela rodar — significa restaurar uma aproximação aceitável desse estado, suficiente do ponto de vista da aplicação, já que outras transações podem ter alterado os mesmos dados nesse meio-tempo. Essa flexibilidade é o que torna sagas implementáveis mesmo sobre sistemas de banco que não oferecem suporte nativo ao conceito.
O trade-off central: atomicidade sem isolamento total
O paper deixa explícito um trade-off que distingue saga de uma transação tradicional: ao permitir que cada subtransação comite e libere seus locks assim que termina, em vez de segurar tudo bloqueado até o fim de todo o processo, uma saga abre mão do isolamento completo que uma transação ACID convencional oferece. Isso significa que, durante a execução de uma saga, outras transações concorrentes podem enxergar e até modificar dados que já foram alterados por subtransações intermediárias da saga, algo que não aconteceria se a saga inteira estivesse protegida por locks do início ao fim. Em troca dessa concessão, a saga ainda entrega uma forma de atomicidade: o processo como um todo termina de forma observável, equivalente a ter sido totalmente concluído ou a nunca ter acontecido, graças ao mecanismo de compensação. Essa troca desloca parte da responsabilidade para quem projeta a saga: cada subtransação precisa ter uma compensação correspondente definida com cuidado, capaz de lidar com o fato de que os dados podem ter sido tocados por outras transações no intervalo, e o paper discute como esse controle pode ser mantido mesmo em sistemas existentes que não têm suporte embutido ao conceito de saga, exigindo esse registro de compensações na camada de aplicação.
Legado: o padrão saga em arquiteturas distribuídas e microsserviços
Embora o paper de 1987 tenha sido escrito pensando em transações dentro de um único sistema de banco de dados, a mesma ideia central — decompor um processo longo em passos menores, cada um com uma ação compensatória associada, em vez de tentar manter uma transação distribuída bloqueante do início ao fim — reaparece décadas depois como base do que hoje é amplamente chamado de "padrão saga" em arquiteturas de microsserviços. Nesse contexto mais moderno, os "passos" deixam de ser subtransações de um mesmo banco e passam a ser chamadas a serviços independentes, cada um com seu próprio armazenamento; como não existe mais um único gerenciador de transações capaz de coordenar um commit distribuído entre todos esses serviços, a lógica de compensação por passo passa a ser responsabilidade explícita de quem projeta o fluxo de negócio, seguindo abordagens como orquestração (um coordenador central dispara cada passo e, se necessário, as compensações) ou coreografia (cada serviço reage a eventos dos anteriores). O que se mantém, em espírito, é exatamente a garantia original do paper: o processo como um todo termina de forma observável como concluído por completo ou desfeito por completo, mesmo sem isolamento total durante sua execução — a mesma troca discutida no artigo original, aplicada agora a sistemas distribuídos que não compartilham um único banco de dados.
Veja as ideias em ação
Pratique na escola de System Design os desenhos que usam este paper.