No PostgreSQL NÃO existem transações aninhadas de verdade do jeito clássico que a galera imagina. O que rola é uma transação externa e "camadas" de pontos de salvamento dentro dela.
O termo "transações aninhadas" no PostgreSQL normalmente quer dizer usar pontos de salvamento (savepoints) com os comandos SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT. Não são transações separadas e independentes, mas sim checkpoints especiais dentro de uma transação externa, pros quais dá pra voltar sem precisar desfazer tudo.
Uma analogia da vida real: você tá escrevendo um textão no editor e vai dando ctrl+s de vez em quando. Se fizer besteira, dá pra voltar pra uma versão salva anterior sem perder todo o progresso.
Comandos pra gerenciar pontos de salvamento
Pra lidar com transações aninhadas, o PostgreSQL te dá três comandos principais:
SAVEPOINT
Esse comando serve pra criar "pontos de salvamento" pros quais você pode voltar se der ruim. O ponto funciona tipo um checkpoint na sua transação.
SAVEPOINT mypoint;
ROLLBACK TO SAVEPOINT
Desfaz parte das alterações feitas depois do ponto indicado, mas deixa intacto o que rolou antes dentro da mesma transação externa.
ROLLBACK TO SAVEPOINT mypoint;
RELEASE SAVEPOINT
Remove o ponto de salvamento. Depois disso, não dá mais pra voltar pra ele.
RELEASE SAVEPOINT mypoint;
Exemplo: adicionando dados em várias tabelas com possibilidade de rollback
Imagina que você tá mexendo num sistema de pedidos, onde precisa salvar dados em duas tabelas: orders e order_items. Se der erro em uma, não pode perder o que já salvou na outra.
BEGIN; -- Início da transação
-- Criando ponto de salvamento
SAVEPOINT before_order;
-- Adicionando pedido na tabela orders
INSERT INTO orders (order_id, customer_id, date)
VALUES (1, 101, CURRENT_DATE);
-- Se der erro aqui — voltamos pro ponto
SAVEPOINT before_order_items;
-- Adicionando itens na tabela order_items
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1, 2001, 4);
-- Se der ruim
-- ROLLBACK TO SAVEPOINT before_order_items;
-- Confirma a transação (salva as mudanças)
COMMIT;
Se na hora de adicionar registros em order_items rolar algum erro, dá pra voltar pro ponto before_order_items, e o que foi salvo em orders continua lá.
Dicas práticas e erros comuns
Agora que você já entendeu como funcionam os comandos SAVEPOINT e ROLLBACK TO SAVEPOINT, se liga nessas dicas pra não cair em cilada:
- Nomes dos pontos de salvamento. Usa nomes claros e únicos pros
SAVEPOINT. Tipobefore_insert,step1e por aí vai — isso ajuda muito na hora de debugar. - Não esquece de liberar o
SAVEPOINT. Se não vai mais precisar voltar pro ponto, remove ele comRELEASE SAVEPOINTpra não deixar a transação bagunçada. - Transação aninhada ≠ transação separada. Lembra que quando você manda um
COMMIT, todos os pontos de salvamento somem. Se oCOMMITexterno já rolou, não tem mais como voltar atrás. - Lock de dados. Mesmo que você volte pra um ponto, os locks feitos na transação continuam. Isso é importante quando tem vários usuários mexendo ao mesmo tempo.
Transações aninhadas usando SAVEPOINT e ROLLBACK TO SAVEPOINT são uma baita ferramenta pra quem desenvolve e precisa lidar com situações complicadas. Agora você pode dividir suas transações em etapas flexíveis, tratar erros de boa e evitar rollback desnecessário. E lembra: toda vez que ouvir "rollback", não precisa entrar em pânico — às vezes, voltar atrás é o melhor jeito de seguir em frente.
GO TO FULL VERSION