Pomysł, którego zazwyczaj używam podczas pracy z transakcjami, wygląda tak (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
}
Zauważ, że w przypadku tego pomysłu, jeśli zapytanie się nie powiedzie, należy zgłosić wyjątek:
- PDO może to zrobić, w zależności od konfiguracji
- Zobacz
PDO::setAttribute
- i
PDO::ATTR_ERRMODE
iPDO::ERRMODE_EXCEPTION
- Zobacz
- w przeciwnym razie, w przypadku niektórych innych API, może być konieczne przetestowanie wyniku funkcji użytej do wykonania zapytania i samodzielne zgłoszenie wyjątku.
Niestety nie ma w tym żadnej magii. Nie możesz po prostu gdzieś umieścić dyspozycji i automatycznie wykonywać transakcji:nadal musisz określić, jaka grupa zapytań ma zostać wykonana w transakcji.
Na przykład dość często będziesz mieć kilka zapytań przed transakcją (przed begin
) i jeszcze kilka zapytań po transakcji (po commit
lub rollback
) i będziesz chciał, aby te zapytania były wykonywane bez względu na to, co się stało (lub nie) w transakcji.