L'idée que j'utilise généralement lorsque je travaille avec des transactions ressemble à ceci (semi-pseudo-code) :
try {
// First of all, let's begin a transaction
$db->beginTransaction();
// A set of queries; if one fails, an exception should be thrown
$db->query('first query');
$db->query('second query');
$db->query('third query');
// If we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
$db->commit();
} catch (\Throwable $e) {
// An exception has been thrown
// We must rollback the transaction
$db->rollback();
throw $e; // but the error must be handled anyway
}
Notez qu'avec cette idée, si une requête échoue, une exception doit être lancée :
- PDO peut le faire, selon la façon dont vous le configurez
- Voir
PDO::setAttribute
- et
PDO::ATTR_ERRMODE
etPDO::ERRMODE_EXCEPTION
- Voir
- Sinon, avec une autre API, vous devrez peut-être tester le résultat de la fonction utilisée pour exécuter une requête et lever vous-même une exception.
Malheureusement, il n'y a pas de magie impliquée. Vous ne pouvez pas simplement mettre une instruction quelque part et faire effectuer des transactions automatiquement :vous devez toujours spécifier quel groupe de requêtes doit être exécuté dans une transaction.
Par exemple, très souvent, vous aurez quelques requêtes avant la transaction (avant le begin
) et quelques autres requêtes après la transaction (après soit commit
ou rollback
) et vous voudrez que ces requêtes soient exécutées quoi qu'il arrive (ou pas) dans la transaction.