Transakcje
Transakcje gwarantują, że albo wykonają się wszystkie operacje w ramach transakcji, albo żadna. Przydają się do zapewnienia spójności danych przy złożonych operacjach.
Najprostszy sposób użycia transakcji wygląda tak:
$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;
}
Ten sam efekt osiągniesz znacznie elegancej metodą transaction(). Przyjmuje ona callback, który wykonywany jest
w ramach transakcji. Jeśli callback zakończy się bez wyjątku, transakcja jest automatycznie zatwierdzana. Jeśli wystąpi
wyjątek, transakcja jest wycofywana, a wyjątek propagowany dalej.
$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'
]);
});
Wywołania transaction() można zagnieżdżać, co ułatwia komponowanie metod, z których każda zarządza
własną transakcją. Do bazy danych jako BEGIN/COMMIT wysyłana jest w rzeczywistości tylko transakcja
zewnętrzna; wewnętrzne wywołania jedynie śledzą głębokość zagnieżdżenia. Ręczne wywołanie
beginTransaction(), commit() albo rollBack() wewnątrz callbacku transaction()
rzuca LogicException.
Metoda transaction() może też zwracać wartości:
$count = $database->transaction(function ($database) {
$result = $database->query('UPDATE users SET active = ?', true);
return $result->getRowCount(); // zwraca liczbę zaktualizowanych wierszy
});