Transactions et validation automatique (autocommit)
Maintenant que vous êtes connecté via PDO, vous devez comprendre
comment PDO gère les transactions avant d'exécuter des requêtes. Si vous n'avez
jamais utilisé les transactions, elles offrent 4 fonctionnalités majeures :
Atomicité, Consistance, Isolation et Durabilité (ACID). En d'autres termes,
n'importe quel travail mené à bien dans une transaction, même s'il est effectué
par étapes, est garanti d'être appliqué à la base de données sans risque, et sans
interférence pour les autres connexions, quand il est validé. Le travail des transactions
peut également être automatiquement annulé à votre demande (en supposant que
vous n'ayez encore rien validé), ce qui rend la gestion des erreurs bien plus
simple dans vos scripts.
Les transactions sont typiquement implémentées pour appliquer
toutes vos modifications en une seule fois ; ceci a le bel effet d'éprouver
radicalement l'efficacité de vos mises à jour. En d'autres termes,
les transactions rendent vos scripts plus rapides et potentiellement plus
robustes (vous devez les utiliser correctement pour jouir de ces bénéfices).
Malheureusement, toutes les bases de données ne prennent pas en charge les transactions,
donc PDO doit s'exécuter en mode "autocommit" lorsque vous ouvrez pour la première
fois la connexion. Le mode "autocommit" signifie que toutes les requêtes que vous
exécutez ont leurs transactions implicites, si la base de données le prend en charge ou
aucune transaction si la base de données ne les prend pas en charge. Si vous avez besoin
d'une transaction, vous devez utiliser la méthode PDO::beginTransaction()
pour l'initialiser. Si le pilote utilisé ne prend pas en charge les transactions, une
exception PDO sera lancée (en accord avec votre gestionnaire d'erreurs : ceci est toujours
une erreur sérieuse). Une fois que vous êtes dans une transaction, vous devez utiliser
la fonction PDO::commit() ou la fonction PDO::rollBack()
pour la terminer, suivant le succès de votre code durant la transaction.
Avertissement
PDO ne vérifie la possibilité d'utiliser des transactions qu'au niveau du pilote.
Si certaines conditions à l'exécution empêchent les transactions de fonctionner,
PDO::beginTransaction() retournera tout de même true
sans erreur si le serveur accepte de démarrer une transaction.
Un exemple serait d'utiliser des transactions sur des tables au format MyISAM
du serveur de base de données MySQL.
Lorsque le script se termine ou lorsque la connexion est sur le point de se fermer,
si vous avez une transaction en cours, PDO l'annulera automatiquement.
Ceci est une mesure de sécurité afin de garantir l'intégrité de vos données
dans le cas où le script se termine d'une façon inattendue. Si vous ne validez pas
explicitement la transaction, alors, on présume que quelque chose s'est mal passé
et l'annulation de la transaction intervient afin de garantir la sécurité de vos données.
Avertissement
L'annulation automatique intervient si vous avez initialisé la transaction via
PDO::beginTransaction(). Si vous avez manuellement
exécuté une requête qui commence une transaction, PDO n'a aucun moyen de
le savoir et donc, n'annulera pas automatiquement cette transaction si quelque
chose s'est mal passé.
Exemple #1 Exécution d'un groupe dans une transaction
Dans l'exemple suivant, supposons que nous allons créer un jeu d'entrées
pour un nouvel employé, dont le numéro d'ID sera 23.
En plus des données de base sur cette personne, nous devons également
lui enregistrer son salaire. Il est très simple d'effectuer deux mises à jour
séparées, mais en les enfermant dans les appels des fonctions
PDO::beginTransaction() et
PDO::commit(), nous garantissons que personne
ne pourra voir ces modifications tant qu'elles ne seront pas complètes.
Si quelque chose tourne mal, le bloc de capture annulera toutes les
modifications effectuées depuis le début de la transaction et affichera
un message d'erreur.
<?php
try {
$dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',
array(PDO::ATTR_PERSISTENT => true));
echo "Connecté\n";
} catch (Exception $e) {
die("Impossible de se connecter : " . $e->getMessage());
}
try {
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
$dbh->exec("insert into salarychange (id, amount, changedate)
values (23, 50000, NOW())");
$dbh->commit();
} catch (Exception $e) {
$dbh->rollBack();
echo "Failed: " . $e->getMessage();
}
?>
Vous n'êtes pas limités dans le nombre de mises à jour dans une transaction ;
vous pouvez également y effectuer des requêtes complexes et bien sûr, utiliser
ces informations pour construire d'autres mises à jour et requêtes ; durant l'activité
de la transaction, vous êtes sûrs que personne d'autre ne peut effectuer des
modifications alors que vous êtes au milieu de vos modifications.
Pour plus d'informations sur les transactions, reportez-vous à la documentation
fournie par votre base de données.