Estendere PDO per gestire le transazioni

Quando un’applicazione è legata ad un database, diventa fondamentale far uso del potenziale del database stesso per far si che i dati siano sempre coerenti e solidi. Si fa uso, ad esempio, delle foreigh key o soluzioni simili, più o meno implementati nei principali database.

Anche i programmatori (do per scontato che dagli sviluppatori in su, questo sia ovvio) dovrebbero seguire semplici regole per salvaguardare la coerenza e la solidità dei dati all’interno del database. Ad esempio, evitare di eseguire le operazioni fin tanto ché tutti i dati siano stati verificati e risultino validi per lo storage nel database.

Tuttavia, il modo migliore per avere sotto controllo l’integrità del database è quello di utilizzare le transazioni. Una transazione inizia con un comando specifico per ogni database. Poi si eseguono tutte le operazioni – salvataggio, modifica, cancellazione – esattamente come siamo abituati a fare. Una volta terminate tutte le operazioni si decide se renderle effettive (comando commit) o se annullarle (comando rollback). L’esecuzione dell’una o dell’altra operazione porta a termine la transazione.

PDO di PHP 5 offre tre comode interfacce per fare questo, tuttavia manca qualcosa e questo qualcosa implementeremo con questo articolo.

Molto spesso mi ritrovo a dover eseguire operazioni concatenate molto complesse ed ibride. A causa di queste caratteristiche, in alcuni punti del codice ho la necessità di eseguire delle transazioni, in altri no.

Tuttavia, potrebbe capitare che si verifichi un errore (o eccezione) all’interno del codice. La corretta scrittura del codice dovrebbe far gestire le eccezioni per mezzo di costrutti appositi, quali ad esempio il try/catch.

Sicuramente la prima cosa da fare, quando si esegue il codice che gestisce le eccezioni, è annullare tutte le operazioni fatte sul database, eseguire cioè il rollback. Comunque, come avevo premesso, l’eccezione potrebbe anche essersi verificata in un contesto dove non si sta eseguendo nessuna transazione.

Ovviamente l’esecuzione del comando rollback, senza alcuna transazione in corso, genera una ulteriore eccezione per cui andrebbero gestite troppe cose.

Stranamente in PDO non c’è nessuna interfaccia che tenga traccia dello stato della transazione: cioè se attiva o meno. Per cui mi sono rimboccato le maniche ed ho esteso la classe PDO in modo da offrire una nuova interfaccia che mi dica che c’è una transazione attiva o meno.

Le tre interfacce che andremo a manipolare sono PDO::beginTransaction()PDO::commit() e PDO::rollBack(). I nomi sono esplicativi.

Ad un ipotetica classe DBO che estende PDO va aggiunta una nuova variabile che ho chiamato hasActiveTransaction di tipo booleano. Se risulta vera allora c’è una transazione in corso, altrimenti non ci sono transazioni.

Aggiungiamo quindi subito questa riga:

Dopo di che aggiungiamo la nostra versione delle tre interfacce precedentemente elencate:

Il funzionamento è semplice: quando attivo la transazione, imposto la variabile hasActiveTransaction. Questa avrà valore true se PDO è stato in grado di attivare la transazione, false nel caso contrario. Le altre due interfacce non fanno altro che riportare a false la variabile, visto che loro determinano la fine di una transazione.

Add a Comment