Transactions
Les transactions garantissent que toutes les opérations qu'elles contiennent sont exécutées, ou bien aucune. Elles sont utiles pour préserver la cohérence des données lors d'opérations complexes.
La façon la plus simple d'utiliser les transactions ressemble à ceci :
$database->beginTransaction();
try {
$database->query('DELETE FROM articles WHERE id = ?', $id);
$database->query('INSERT INTO audit_log', [
'article_id' => $id,
'action' => 'delete'
]);
$database->commit();
} catch (\Exception $e) {
$database->rollBack();
throw $e;
}
Vous pouvez obtenir le même résultat de façon bien plus élégante à l'aide de la méthode transaction(). Elle
accepte un callback qui est exécuté à l'intérieur de la transaction. Si le callback s'exécute sans exception, la transaction
est validée automatiquement. Si une exception survient, la transaction est annulée et l'exception est propagée plus loin.
$database->transaction(function ($database) use ($id) {
$database->query('DELETE FROM articles WHERE id = ?', $id);
$database->query('INSERT INTO audit_log', [
'article_id' => $id,
'action' => 'delete'
]);
});
Les appels à transaction() peuvent être imbriqués, ce qui permet de composer facilement des méthodes gérant
chacune sa propre transaction. Seule la transaction la plus externe est réellement envoyée à la base sous forme de
BEGIN/COMMIT ; les appels internes se contentent de suivre la profondeur d'imbrication. Appeler
manuellement beginTransaction(), commit() ou rollBack() à l'intérieur d'un callback de
transaction() lève une LogicException.
La méthode transaction() peut aussi renvoyer des valeurs :
$count = $database->transaction(function ($database) {
$result = $database->query('UPDATE users SET active = ?', true);
return $result->getRowCount(); // renvoie le nombre de lignes mises à jour
});