CodeGym /Corsi /SQL SELF /Uso di SAVEPOINT per gestire rollback parzi...

Uso di SAVEPOINT per gestire rollback parziali nelle transazioni

SQL SELF
Livello 39 , Lezione 2
Disponibile

Immagina di scrivere un libro. Ma ecco il problema: non sempre tutto va secondo i piani. A volte scrivi un intero capitolo, ma quando lo rileggi capisci che il quinto paragrafo è venuto malissimo. Che fai? Non butti via tutto il capitolo, giusto? Invece, modifichi solo le parti che ti fanno dubitare.

Funziona più o meno così anche SAVEPOINT in PostgreSQL. Ti permette di:

  1. Creare punti di salvataggio dentro una transazione — come dei segnalibri in un libro.
  2. Tornare a questi punti per annullare solo una parte delle operazioni fatte, senza fare rollback di tutta la transazione.
  3. Continuare a lavorare con i dati rimasti, senza dover ricominciare tutto da capo.

Sintassi base di SAVEPOINT

I comandi collegati all’uso di SAVEPOINT sono piuttosto semplici. Ecco il set base:

Creare un punto di salvataggio (SAVEPOINT):

SAVEPOINT savepoint_name;

È come dire: "Segniamoci questo punto, magari dopo ci serve tornarci."

Rollback al punto di salvataggio creato (ROLLBACK TO SAVEPOINT):
ROLLBACK TO SAVEPOINT savepoint_name;

Se qualcosa va storto, torni al SAVEPOINT indicato e annulli tutte le modifiche fatte da quando l’hai creato.

Eliminare un punto di salvataggio (RELEASE SAVEPOINT):
RELEASE SAVEPOINT savepoint_name;

Questo libera lo spazio dove c’era il "segnalibro". Dopo non puoi più fare rollback a quel punto.

Esempio semplice: acquisto in un e-commerce

Immagina che stiamo gestendo un negozio online. Un cliente aggiunge diversi prodotti al carrello e vogliamo fare una transazione che comprende la creazione dell’ordine e la modifica delle giacenze in magazzino. Però, se uno dei passaggi fallisce, vogliamo annullare solo una parte della transazione, non tutto.

BEGIN;

-- Passo 1: Prenotare il prodotto "Libro SQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;

-- Creiamo un punto di salvataggio
SAVEPOINT book_reserved;

-- Passo 2: Prenotare il prodotto "Tazza PostgreSQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 102;

-- Ops, si scopre che non ci sono tazze in magazzino!
ROLLBACK TO SAVEPOINT book_reserved;

-- Confermiamo le modifiche solo per il libro
COMMIT;

Cosa succede in questo esempio?

  1. Abbiamo iniziato la transazione con BEGIN.
  2. Dopo aver prenotato il libro, abbiamo creato il punto di salvataggio book_reserved. È il nostro primo "checkpoint".
  3. Abbiamo provato a prenotare la tazza, ma c’è stato un errore (tipo, la tazza non c’era in magazzino).
  4. Siamo tornati al punto di salvataggio book_reserved per annullare solo le modifiche legate alla tazza.
  5. Infine, abbiamo confermato le modifiche per il libro con COMMIT.

Esempio più complesso: elaborazione dati multi-step

Ora immagina di lavorare con un sistema di gestione ordini dove devi aggiornare più tabelle: orders (ordini), inventory (giacenze) e billing (fatturazione). Se qualcosa va storto in uno dei passaggi, non vuoi perdere i progressi fatti sulle altre tabelle. Qui SAVEPOINT ti salva la vita.

BEGIN;

-- Passo 1: Creare un nuovo ordine
INSERT INTO orders (order_id, customer_id, status) VALUES (1, 123, 'in attesa');
SAVEPOINT after_order_created;

-- Passo 2: Aggiornare le giacenze in magazzino
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
SAVEPOINT after_stock_updated;

-- Passo 3: Effettuare il pagamento
INSERT INTO billing (order_id, amount, status) VALUES (1, 100, 'pagato');

-- Ops, errore: carta di credito rifiutata!
ROLLBACK TO SAVEPOINT after_stock_updated;

-- Siamo tornati al passo dopo l’aggiornamento delle giacenze, ma l’ordine resta con stato "in attesa".
UPDATE orders SET status = 'fallito' WHERE order_id = 1;

COMMIT;

Nota come con SAVEPOINT abbiamo diviso la transazione in step logici e siamo tornati al punto giusto, mantenendo parte delle modifiche.

Consigli utili quando usi SAVEPOINT

  • Usa nomi significativi per i punti di salvataggio. Negli esempi sopra after_order_created è molto più chiaro di un semplice step1.
  • I punti di salvataggio annidati funzionano bene: puoi creare SAVEPOINT anche dentro un rollback a un altro punto.
  • Libera risorse eliminando i punti inutili con RELEASE SAVEPOINT. Questo può migliorare le performance, specialmente in transazioni grosse.

Scenari reali di utilizzo

Gestione di operazioni bancarie: Per esempio, quando trasferisci soldi tra più conti puoi tornare a uno step preciso se uno dei trasferimenti fallisce.

Importazione dati da file: Se importi un grosso file CSV, puoi controllare ogni riga e fare rollback solo per i dati sbagliati, mantenendo quelli andati a buon fine.

Aggiornamento massivo di record: Se hai uno script SQL complesso che aggiorna migliaia di righe, SAVEPOINT ti permette di tornare allo step precedente se c’è un errore a metà esecuzione.

Errori tipici e trappole

A volte usare SAVEPOINT può portare a risultati inaspettati se non capisci bene come funziona. Per esempio:

  • Se ti dimentichi di fare rollback o eliminare un punto di salvataggio, puoi creare situazioni dove le risorse restano bloccate fino alla fine della transazione.
  • SAVEPOINT non può annullare azioni fatte prima della sua creazione. Per esempio, i dati confermati con COMMIT non si possono più annullare.

Ora puoi sperimentare in sicurezza nelle transazioni, creando punti di salvataggio dove serve. Ci aspettano ancora più esercizi SQL, quindi preparati al prossimo round di avventure.

2
Compito
SQL SELF, livello 39, lezione 2
Bloccato
Annullamento semplice delle modifiche con `SAVEPOINT`
Annullamento semplice delle modifiche con `SAVEPOINT`
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION