Lezioni del modulo (4/4)
Transazioni: tutto o niente
Una transazione è un gruppo di operazioni che il database tratta come
una sola unità: o riescono tutte, o non ne resta traccia di nessuna.
È il modo in cui ci si protegge da incoerenze quando una sequenza di
UPDATE/INSERT/DELETE deve restare consistente.
La sintassi
BEGIN; -- apri la transazione
UPDATE …;
INSERT …;
DELETE …;
SELECT …; -- puoi anche solo leggere
COMMIT; -- conferma tutte le modifiche
-- oppure
ROLLBACK; -- annulla tutte le modifiche, come se nulla fosseTutto quel che sta fra BEGIN e COMMIT è atomico: nessun'altra
connessione vede lo stato intermedio. Se il programma crasha o esegue
ROLLBACK, il database resta esattamente come prima del BEGIN.
Lo scenario classico: il trasferimento
L'esempio canonico è un trasferimento di stock fra prodotti (o di soldi
fra conti): due UPDATE che devono andare a buon fine insieme, mai
una sì e l'altra no.
BEGIN;
UPDATE products SET stock = stock - 1 WHERE id = 1;
UPDATE products SET stock = stock + 1 WHERE id = 2;
COMMIT;Se il secondo UPDATE fallisce (es. errore di vincolo CHECK), un
ROLLBACK riporta lo stock del prodotto 1 al valore originale.
ROLLBACK: il debugger del DBA
BEGIN;
UPDATE customers SET city = 'X' WHERE id = 1;
SELECT first_name, city FROM customers WHERE id = 1; -- "vedo come è cambiato"
ROLLBACK;Pattern molto utile per provare un UPDATE su dati reali: lo esegui,
guardi il risultato con una SELECT nella stessa transazione, e se non
ti convince fai ROLLBACK — il database è esattamente come prima.
SAVEPOINT: rollback parziale
Dentro una transazione puoi creare punti intermedi:
BEGIN;
UPDATE customers SET city = 'A' WHERE id = 1;
SAVEPOINT step1;
UPDATE customers SET city = 'B' WHERE id = 2;
-- mi sono accorto che il secondo UPDATE è sbagliato:
ROLLBACK TO SAVEPOINT step1;
COMMIT; -- solo il primo UPDATE viene confermatoACID in 30 secondi
Le transazioni garantiscono le proprietà ACID:
- Atomicity — tutto o niente;
- Consistency — i vincoli restano rispettati a inizio e fine transazione;
- Isolation — concorrenti non vedono stati intermedi (a vari "livelli");
- Durability — un
COMMITriuscito non si perde nemmeno in caso di crash.
Prova tu
In una sola transazione: decrementa di 1 lo stock del prodotto 1 e incrementa di 1 lo stock del prodotto 2. Apri con BEGIN e chiudi con COMMIT.
Mostra suggerimento
Riferisci stock - 1 e stock + 1 nei rispettivi SET.
Soluzione disponibile dopo 3 tentativi
Esercizio di ripasso
Apri una transazione, prova ad aggiornare la città del cliente con id=1 a 'Sperimentale', poi annulla l'operazione con ROLLBACK. Alla fine la città del cliente 1 deve essere quella originale ('Milano').
Mostra suggerimento
ROLLBACK annulla tutte le modifiche fatte dal BEGIN in poi.
Soluzione disponibile dopo 3 tentativi