75 PDO5 transazioni
Immaginiamo di dover fare un po’ di pulizia, cancellando i questionari più vecchi di tot anni e poi cancellare gli utenti iscritti prima di tale data e con zero privi di questionari svolti.
Sarebbero 2 operazioni di delete, la cancellazione questionari e quella utenti. Supponiamo che per qualsiasi motivo lo script inizia e prima di terminare si blocca, si tratta di casi chiamati di perdita di consistenza a causa di operazioni non completate. Il meccanismo transazionale è stato introdotto per ovviare a tali inconvenienti. Le transazioni sono uno script di comandi SQL per cui il sistema che le esegue assicura che o tutte quelle operazioni dello script vengano eseguite correttamente, oppure che è in grado di accorgersi dell’anomalia riportando la situazione allo stato precedente all’esecuzione (roll back del database).
Saltando la solita parte di inclusione e connessione vediamo ora la parte delle transaction della nuova pagina transazione_PDO.php. Il supporto per le transazione di MySQL supporta perfettamente il try/catch del php.
Iniziamo una transazione col metodo beginTransaction:
try
{
$conn->beginTransaction();
Prepariamo poi il comando che canchella i questionari anteriori al primo gennaio 2002:
$comandoSQL ="delete from questionari_svolti where fine<'2002-01-01'";
Lo eseguiamo col metodo exec, da usare quando non ci si aspetta un ritorno di risultato di righe.
Stessa cosa per gli utenti:
$comandoSQL = "delete from users where iduser not in ".
"(select fkuser from questionari_svolti)";
$conn->exec($comandoSQL);
Tra il primo comando e il secondo potrebbere verificarsi una anomalia che blocca l’esecuzione, avendo istanziato una transazione, i dati sul database non vengono cancellati permanentemente, fino a quando non viene eseguita la conferma tramite il comando commit:
$conn->commit();
Se viene eseguita questa riga, le operazioni sono andate a buon fine e le modifiche vengono rese permanenti. Se avviene l’anomalia, il blocco try si interrompe, insieme al comando commit e si passa al blocco catch:
catch (Exception $e)
{
$conn->rollBack();
echo "Pulizia archivi fallita ".$nl;
die();
}
Con il rollback il database viene riportato allo stato precedente.
Di seguito il codice completo della pagina:
<?php
include($_SERVER['DOCUMENT_ROOT']."/fagtest/my_include/setup_con_DB.php");
//recupero credenziali da file ESTERNO alla cartella pubblica del sito
try
{
//CONNESSIONE
$conn = new PDO("mysql:host=localhost;dbname={$accessData['dbname']}",
$accessData['username'],$accessData['password']);
}
catch (PDOException $e)
{
echo $e->getMessage() . "<br/>";
echo "Connessione al server fallita. Impossibile procedere. Contattare ...";
die();
}
//ATTIVAZIONE ECCEZIONI PER METODO QUERY
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try
{
$conn->beginTransaction();
$comandoSQL ="delete from questionari_svolti where fine<'2002-01-01'";
$conn->exec($comandoSQL);
//dopo l'esecuzione del precedente comando e quella del seguente
//potrebbere verificarsi una anomalia che blocca l'esecuzione
//sul server ...
//verrebbe sollevata l'eccezione, saltato il commit e comandato il rollback
//controlli ...
/* $errore=true;
if($errore)
$conn->rollBack(); //annulliamo le operazioni precedenti
else
{
$comandoSQL = "delete from users where iduser not in ".
"(select fkuser from questionari_svolti)";
$conn->exec($comandoSQL);
//se siamo arrivati qui rendiamo permanenti le modifiche
$conn->commit();
}
*/
$comandoSQL = "delete from users where iduser not in ".
"(select fkuser from questionari_svolti)";
$conn->exec($comandoSQL);
//se siamo arrivati qui rendiamo permanenti le modifiche
$conn->commit();
}
catch (Exception $e)
{
$conn->rollBack();
echo "Pulizia archivi fallita ".$nl;
die();
}
//CHIUDIAMO LA CONNESSIONE E LIBERIAMO LE RISORSE OCCUPATE ...
$conn=null;