O uso do savepoint no PL/SQL
Introdução
O SAVEPOINT é um recurso do PL/SQL que permite definir pontos intermediários em uma transação. Esses pontos servem como marcadores, permitindo que o sistema reverta apenas uma parte da transação, em vez de desfazer toda a operação.
Sintaxe Básica
SAVEPOINT nome_savepoint;
VANTAGENS
- Permite reverter apenas parte de uma transação.
- Oferece maior controle sobre as operações complexas.
- Melhora a integridade e segurança dos dados.
DESVANTAGENS/LIMITAÇÕES
- Não pode desfazer operações DDL (como CREATE ou ALTER).
- Os SAVEPOINTs são automaticamente descartados após o COMMIT.
- Pode aumentar o consumo de recursos em transações muito longas.
Quando Usar SAVEPOINT
Operações Longas: Quando uma transação envolve várias etapas, e você deseja garantir que apenas algumas operações sejam revertidas em caso de falha.
Validações Parciais: Em processos que precisam de validação intermediária antes de prosseguir.
Tratamento de Exceções: Quando se espera que erros possam ocorrer em algumas operações, mas deseja-se manter as operações anteriores intactas.
Exemplos práticos
Imagine um sistema de pagamento onde se deve registrar o pedido e o pagamento separadamente:
BEGIN
INSERT INTO pedidos (id_pedido, descricao) VALUES (1, 'Compra de Eletrônicos');
SAVEPOINT pedido_criado;
INSERT INTO pagamentos (id_pagamento, id_pedido, valor) VALUES (1, 1, 500);
SAVEPOINT pagamento_registrado;
-- Simulando um erro
INSERT INTO entrega (id_entrega, id_pedido) VALUES (1, 999); -- Pedido inexistente
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO pagamento_registrado;
DBMS_OUTPUT.PUT_LINE('Erro na entrega. Pagamento mantido.');
END;
Se ocorrer um erro na entrega, o pagamento permanece salvo, mas o pedido não é afetado.
Atualização de informações de um cliente com rollback parcial.
BEGIN
UPDATE clientes SET nome = 'João Silva' WHERE id_cliente = 101;
SAVEPOINT nome_atualizado;
UPDATE clientes SET endereco = 'Rua Nova, 123' WHERE id_cliente = 101;
SAVEPOINT endereco_atualizado;
-- Simulando erro na atualização de email
UPDATE clientes SET email = 'email_invalido.com' WHERE id_cliente = 101;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO endereco_atualizado;
DBMS_OUTPUT.PUT_LINE('Erro ao atualizar email. Nome e endereço mantidos.');
END;
Conclusão
Algumas considerações importantes quanto ao uso do SAVEPOINT são: Use SAVEPOINT para transações críticas que envolvam várias tabelas, sempre nomeie os savepoints de forma significativa e não exagere na criação de savepoints, pois isso pode impactar o desempenho.
Referências