La gestion des transactions se base sur l'API fournie par PDO.

Vos tables doivent être en
InnoDB
pour pouvoir participer à une transaction. Le format MyISAM n'est pas supporté.

Seules les requêtes UPDATE, INSERT, DELETE
sont concernées par les transactions. Si vous avez des requêtes CREATE, DROP, ALTER ou autres au milieu de votre
transaction, un COMMIT sera envoyé et l'unicité de la transaction ne sera pas assurée.
Transaction basique
Il est conseillé de suivre ce pattern pour implémenter les transactions :
<?php
$db = DBHelper::getInstance(DB_DATABASE_TEST);
try {
$db->beginTransaction();
$db->execUpdate(...);
$db->execUpdate(...);
$db->execUpdate(...);
if (something_wrong) {
$db->rollback();
} else {
$db->commit();
}
} catch (Exception $ex) {
$db->rollback();
}
Si aucun commit ou rollback n'est exécuté avant la fin de la page, PDO va automatiquement faire un rollback de la transaction,
le rollback est donc facultatif mais il est quand même conseillé pour gérer les choses proprement.
Vous pouvez également appeler l'API
DBHelper::checkAllTransactionsEnded() à la fin de votre page qui va lever une
exception si une transaction est encore en cours.
Transactions imbriquées
Les transactions imbriquées sont possibles et fonctionnent de la manière suivante :
- Seul le 1er appel à beginTransaction() démarre réellement la transaction
- Seul le commit() ou le rollback() du même niveau que le 1er beginTransaction() termine réellement la transaction
- Tout rollback() rencontré lors de la transaction fera que la transaction de plus haut niveau partira en rollback
<?php
$db->beginTransaction(); // démarrage réel de la transaction : niveau 0
method()
$db->beginTransaction(); // ne fait rien à part passer au niveau 1
sousMethod()
$db->beginTransaction(); // ne fait rien à part passer au niveau 2
...
$db->commit(); // ne fait rien à part descendre au niveau 1
$db->rollback(); // marque la transaction pour rollback sans réaliser le rollback et passe au niveau 0
// on est au niveau 0 : commit réel de la transaction en théorie, sauf qu'on rollback car une
// des transactions précédentes a fait un rollback()
$db->commit();
Vérifier qu'on est dans une transaction
Vous pouvez vérifier qu'une transaction est active avec
$db->inTransaction()
<?php
function doing_something_that_require_transaction($db) {
if (!$db->inTransaction()) {
throw new \Exception('Une transaction est requise');
}
...
}