Commit e Rollback, ovvero come limitare i danni

In tutti i database relazionali minimamente decenti esistono due comandi fondamentali che rispondono per l' appunto al nome di commit e rollback. questi due comandi provvedono a fare in modo che una determinata operazione venga effettuata come un tutto unico o che non venga effettuata per niente. vediamo di capire cosa significa.

Mettiamo che voi stiate gestendo il database di una banca e che dobbiate effettuare un bonifico bancario; questa operazione in realtà si divide in almeno due distinte operazioni:

1. aumentare il saldo del conto corrente del destinatario della cifra in esame

2. diminuire il saldo del conto corrente del mittente della stessa cifra più quella dovuta per le commissioni

ora, cosa succederebbe se a metà dell' operazione il sistema avesse dei problemi (stile corrente che salta, un errore logico come la mancanza del record del destinatario, un processore fuso per il troppo calore,un impiegato impazzito con grosso martellone che picchia sul server)? a seconda dell' ordine in cui le effettuate potete avere i seguenti risultati:

1. i soldi vengono tolti dal cc del mittente e non arrivano in quello del destinatario: risultato il destinatario del bonifico vuole il vostro sangue

2. i soldi NON vengono tolti dal cc del mittente, arrivano in quelli del destinatario e la banca ce li rimette: risultato dovete cercarvi in fretta un'altro lavoro DOPO averli sborsati voi

entrambi i risultati non brillano per piacevolezza, ma per fortuna vi vengono incontro i due comandi suddetti. come funzionano?

Quando si fa qualcosa che deve venire gestito come un tutt' uno si inizia la procedura con una istruzione BEGIN TRANSACTION, che indica il punto di inizio del nostro codice "a rischio" . a questo punto il nostro database non esegue più le variazioni direttamente sul disco ma in una particolare area temporanea (normalmente in memoria) e se la tiene parcheggiata lì finché non sente un comando COMMIT. a quel punto in un' unica soluzione fa TUTTE le variazioni che ha precalcolato in contemporanea. nel caso qualcosa andasse storto l' intera transazione andrebbe persa e quindi il bonifico non verrebbe fatto, sicuramente una situazione meno spiacevole di quella citata prima (anche perché può venire rifatto). E' inoltre possibile forzare questo avvenimento tramite l' istruzione ROLLBACK nel caso che il problema sia di tipo software (esempio ho gli estremi del mittente ma in tabella non esiste il destinatario, quindi sebbene sia già partito a togliere i soldi dal primo non posso metterli sul secondo) . un tipico esempio di gestione commit-rollback può essere la seguente:

BEGIN TRANSACTION; // inizio della transazione

USE banca1; // utilizza il database di nome BANCA1

UPDATE conticorrenti // aggiorna la tabella dei conti correnti

SET saldo = saldo + 1000000 // aggiungendo un milione al saldo

WHERE ccn = 181818 // del conto corrente numero 181818

ON ERROR ROLLBACK; // in caso di un qualunque errore effettua un rollback ed annulla tutto

USE banca2; // utilizza il database di nome BANCA2

UPDATE conticorrenti // aggiorna la tabella dei conti correnti

SET saldo = saldo - 1000000 // sottraendo un milione al saldo

WHERE ccn = 161616; // del conto corrente numero 161616

ON ERROR ROLLBACK; // in caso di un qualunque errore effettua un rollback ed annulla tutto

COMMIT; // effettua tutta la transizione in una volta

attenzione, l' esempio fatto sopra e' un classico esempio di più ISTRUZIONI inserite in un' unica transazione , ma in genere se non specifichiamo nulla ogni singola istruzione viene gestita come una transazione a se stante, pertanto se durante l' esecuzione della nostra update su due milioni di campi crolla il sistema, le procedure di ripristino provvederanno a fare si che NESSUNA modifica della due milioni che stavamo facendo compaia, il che e' incredibilmente preferibile al non sapere su quali record la modifica e' già stata apportata e su quali no