2 commenti php

Nel breve percorso volto ad illustrare le funzionalità del sistema PDO illustrato nei precedenti articoli l'ultimo tassello per completare il quadro è costrituito dalle transaction (o in italiano le transazioni). Anzitutto cerchiamo di capire in termini molto semplici in cosa consistono.

 

Le transazioni sono un meccanismo che regola le interazioni con il nostro database che ci consente di eseguire simultaneamente una pluralità di operazioni sul nostro database come se fossero un'unica operazione.

Una transazione potrà terminare con il COMMIT, che determina l'esecuzione simultanea di tutte el operazioni o con il ROLLBACK per l'annullamento.

 

Tipicamente le transazioni sono utili nei casi in cui occorre effettuare una pluralità di query logicamente collegate tra loro, tale che l'eventuale fallimento di una delle query richiede l'annullamento (il ROLLBACK) di tutte le operazioni nell'ambito della tranzazione.

 

I metodi per gestire le transaction

I metodi di cui disporremo per gestire le transazioni sono:

  • PDO->beginTransaction(): avvia la transazione; se la tipologia di database non supporta le transazioni darà come return FALSE, metre ci darà TRUE negli altri casi;
  •  PDO->commit(): esegue le operazioni che fanno parte della transazione; 
  • PDO->rollBack(): annulla le operazioni eseguite nell'ambito della transazione.

 

Ecco di seguito come varranno usati tali metodi 

try{
	/*settiamo il gestore degli errori*/
	$PDO->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
	
	/*iniziamo una transaction*/
	$PDO->beginTransaction();
	
	/*gruppo di query che fanno parte della transaction*/
	$PDO->exec("DELETE FROM people WHERE id=1");
	$PDO->exec("DELETE FROM message WHERE id_people=1"); 
	
	/*eseguiamo le query comprese nella transaction*/
	$PDO->commit();
	}
 // se qualcosa non è andato a buon fine
catch(PDOException $e){	
	/*ritorna tutto come prima della transazione*/
	$PDO->rollBack();
	
	/*stampiamo il messaggio di errore*/
	echo $e->getMessage();
	}

 

I commenti al codice sono già di per sè autoesplicativi quindi non aggiungo altro.

 

Problemi di compatibilità

Sfortunatamente non tutti i database supportano le transazioni. In questo caso il metodo PDO->beginTransaction() ci darà come return FALSE. 

 

Occorre porre l'attenzione su un aspetto. Il return di PDO->beginTransaction esegue un controllo solo a livello di driver. 

Ad esempio MySql supporta le transazioni e, quindi, PDO->beginTransaction() ci darà come return TRUE. Tuttavia le transazioni non funzionano su tabelle di tipo MyISAM con la conseguenza che seppur PDO->beginTransaction darà come return TRUE, PDO->rollBack() non sortisce i suoi effetti.

 

Conclusioni

Si conclude qui questa breve descrizione del sistema PDO e ovviamente per ulterori info e dettagli si rimanda alla documentazione ufficiale. 

 

I programmatori particolamente rigorosi della programmazione ad oggetti ritengono doveroso l'utilizzo del PDO quando si interagisce con il database: esso è sicuramente il miglior metodo in termini di velocità e sicurezza.

 

Per chi è abituato (come me) all'uso delle funzioni "tradizionali" il passaggio ad una nuova metodologia non sarà indolore ma sono certo che alla lunga potrà dare i suoi benefici.

Olimpio Romanella

Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.

Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.

2 Commenti presenti

avatar oly1982

oly1982

24 September 2011 ore 12:58

Anzitutto grazie per il feedback.

Ho eseguito dei test in locale.

Sulle tabelle InnoDB le transaction funzionano regolarmente.
E' sulle tabelle MyISAM che invece non mi funzionano (come ho scritto nel post).

Inoltre credo (ma posso sbagliarmi) che ciò non dipenda dalla versione di MySql quanto piuttosto dal fatto che le tabelle MyISAM non supportano di per se le transazioni Transactions and Atomic Operations.

avatar aras

aras

24 September 2011 ore 11:46

Ciao, argomento interessante.

Volevo solo segnalarti che con php 5.3.8 anche le tabelle di tipo InnoDB non risentono delle transazioni. Difatti il codice da te proposto nel esempio modificato per il drop in tabella di tipo InnoDB fa esattamente quello che la query dice (DROP TABLE).

try{
/*settiamo il gestore degli errori*/
$PDO->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

/*iniziamo una transaction*/
$PDO->beginTransaction();

/*gruppo di query che fanno parte della transaction*/
$PDO->exec("DROP TABLE users");

/*eseguiamo le query comprese nella transaction*/
$PDO->commit();
}
// se qualcosa non è andato a buon fine
catch(PDOException $e){
/*ritorna tutto come prima della transazione*/
$PDO->rollBack();

/*stampiamo il messaggio di errore*/
echo $e->getMessage();
}



Dump della tabella users
-- phpMyAdmin SQL Dump
-- version 3.4.3.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generato il: Set 24, 2011 alle 11:44
-- Versione del server: 5.5.14
-- Versione PHP: 5.3.8

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Database: `webmail`
--

-- --------------------------------------------------------

--
-- Struttura della tabella `users`
--

CREATE TABLE IF NOT EXISTS `users` (
`username` varchar(15) NOT NULL,
`mail` varchar(25) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;