Transacciones
Las transacciones garantizan que, o se ejecutan todas las operaciones de la transacción, o no se ejecuta ninguna. Son útiles para asegurar la consistencia de los datos en operaciones complejas.
La forma más sencilla de usar transacciones es esta:
$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;
}
El mismo resultado se consigue de forma mucho más elegante con el método transaction(). Acepta un callback que
se ejecuta dentro de la transacción. Si el callback se ejecuta sin excepción, la transacción se confirma automáticamente. Si
se produce una excepción, la transacción se revierte y la excepción se propaga hacia arriba.
$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'
]);
});
Las llamadas a transaction() se pueden anidar, lo que facilita componer métodos que gestionan cada uno su propia
transacción. Solo la transacción más externa se envía realmente a la base de datos como
BEGIN/COMMIT; las llamadas internas se limitan a llevar la cuenta del nivel de anidamiento. Llamar
manualmente a beginTransaction(), commit() o rollBack() dentro de un callback de
transaction() lanza una LogicException.
El método transaction() también puede devolver valores:
$count = $database->transaction(function ($database) {
$result = $database->query('UPDATE users SET active = ?', true);
return $result->getRowCount(); // devuelve el número de filas actualizadas
});