CodeGym /Cursos /SQL SELF /Usando SAVEPOINT pra controlar rollbacks pa...

Usando SAVEPOINT pra controlar rollbacks parciais em transações

SQL SELF
Nível 39, Lição 2
Disponível

Imagina que você tá escrevendo um livro. Mas aí, nem sempre tudo sai como planejado. Às vezes você escreve um capítulo inteiro, mas quando relê percebe que o 5º parágrafo ficou horrível. O que você faz? Você não joga o capítulo inteiro no lixo, né? Em vez disso, você edita só as partes que não ficaram legais.

É mais ou menos assim que o SAVEPOINT funciona no PostgreSQL. Ele te permite:

  1. Criar pontos de salvamento dentro da transação — tipo marcadores num livro.
  2. Voltar pra esses pontos pra desfazer só uma parte das operações, sem precisar dar rollback na transação inteira.
  3. Continuar trabalhando com o resto dos dados, sem ter que começar tudo de novo.

Sintaxe básica do SAVEPOINT

Os comandos pra usar SAVEPOINT são bem tranquilos. Olha só o básico:

Criando um ponto de salvamento (SAVEPOINT):

SAVEPOINT savepoint_name;

É tipo falar: "Vamos marcar esse lugar, vai que eu precise voltar aqui depois."

Voltando pra um ponto de salvamento (ROLLBACK TO SAVEPOINT):
ROLLBACK TO SAVEPOINT savepoint_name;

Se deu ruim em alguma coisa, você volta pro SAVEPOINT que marcou e desfaz tudo que rolou depois dele.

Removendo um ponto de salvamento (RELEASE SAVEPOINT):
RELEASE SAVEPOINT savepoint_name;

Isso libera o espaço onde tava o "marcador". Depois disso, não dá mais pra voltar pra esse ponto.

Exemplo simples: compra numa loja online

Imagina que a gente tá gerenciando uma loja online. O cliente coloca vários produtos no carrinho, e a gente quer fazer uma transação que inclui fechar o pedido e atualizar o estoque. Mas, se alguma etapa der ruim, a gente quer desfazer só uma parte da transação, não tudo.

BEGIN;

-- Passo 1: Reservar o produto "Livro SQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;

-- Criando o ponto de salvamento
SAVEPOINT book_reserved;

-- Passo 2: Reservar o produto "Caneca PostgreSQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 102;

-- Ih, descobrimos que não tem caneca no estoque!
ROLLBACK TO SAVEPOINT book_reserved;

-- Confirma só a mudança do livro
COMMIT;

O que tá rolando nesse exemplo?

  1. A gente começou a transação com BEGIN.
  2. Depois de reservar o livro, criamos o ponto de salvamento book_reserved. Esse é nosso primeiro "checkpoint".
  3. Tentamos reservar a caneca, mas deu erro (tipo, não tinha o produto no estoque).
  4. A gente voltou pro ponto book_reserved pra desfazer só o que rolou com a caneca.
  5. No fim, confirmamos só a mudança do livro com COMMIT.

Exemplo mais avançado: processamento de dados em várias etapas

Agora imagina que você tá mexendo num sistema de pedidos, onde precisa atualizar várias tabelas: orders (pedidos), inventory (estoque) e billing (faturamento). Se der erro em algum passo, você não quer perder o que já fez nas outras tabelas. É aí que o SAVEPOINT salva o rolê.

BEGIN;

-- Passo 1: Criar novo pedido
INSERT INTO orders (order_id, customer_id, status) VALUES (1, 123, 'pendente');
SAVEPOINT after_order_created;

-- Passo 2: Atualizar estoque
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
SAVEPOINT after_stock_updated;

-- Passo 3: Fazer o pagamento
INSERT INTO billing (order_id, amount, status) VALUES (1, 100, 'pago');

-- Ih, erro: cartão de crédito recusado!
ROLLBACK TO SAVEPOINT after_stock_updated;

-- Voltamos pro passo depois do estoque, mas o pedido ainda tá como "pendente".
UPDATE orders SET status = 'falhou' WHERE order_id = 1;

COMMIT;

Repara como a gente usou SAVEPOINT pra dividir a transação em etapas lógicas e voltou pro ponto certo, mantendo parte das mudanças.

Dicas úteis pra usar SAVEPOINT

  • Usa nomes de pontos de salvamento que façam sentido. Nos exemplos acima, after_order_created é bem mais claro que só step1.
  • Pontos de salvamento aninhados funcionam de boa: dá pra criar SAVEPOINT até dentro de um rollback pra outro ponto.
  • Libera recursos removendo pontos que não vai mais usar com RELEASE SAVEPOINT. Isso pode deixar tudo mais rápido, principalmente em transações grandes.

Cenários reais de uso

Processamento de operações bancárias: Por exemplo, ao transferir grana entre várias contas, você pode voltar pra um passo específico se uma das transferências falhar.

Importação de dados de arquivos: Se você tá importando um arquivo CSV grandão, pode checar cada linha e dar rollback só nos dados que deram erro, mantendo o que já foi de boa.

Atualização em massa de registros: Se você tem um script SQL cabuloso pra atualizar milhares de linhas, SAVEPOINT deixa você voltar pra um passo anterior se der erro no meio do caminho.

Erros comuns e pegadinhas

Às vezes usar SAVEPOINT pode dar uns resultados estranhos se você não sacar como funciona. Por exemplo:

  • Se você esquecer de voltar pra um ponto de salvamento ou remover ele, pode acabar travando recursos até a transação acabar.
  • SAVEPOINT não desfaz o que rolou antes do ponto ser criado. Tipo, dados confirmados com COMMIT não tem mais volta.

Agora você já pode brincar tranquilo com transações, criando pontos de salvamento onde precisar. Vem mais prática de SQL por aí, então se prepara pro próximo desafio!

2
Tarefa
SQL SELF, nível 39, lição 2
Bloqueado
Cancelamento simples de alterações usando `SAVEPOINT`
Cancelamento simples de alterações usando `SAVEPOINT`
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION