Myšlenka, kterou obecně používám při práci s transakcemi, vypadá takto (semi-pseudo-kód) :
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
}
Všimněte si, že s tímto nápadem, pokud dotaz selže, musí být vyvolána výjimka:
- PDO to dokáže v závislosti na tom, jak jej nakonfigurujete
- Viz
PDO::setAttribute
- a
PDO::ATTR_ERRMODE
aPDO::ERRMODE_EXCEPTION
- Viz
- jinak u některých jiných rozhraní API možná budete muset otestovat výsledek funkce použité k provedení dotazu a sami vyvolat výjimku.
Bohužel v tom není žádná magie. Nemůžete jen tak někam vložit pokyn a nechat transakce provádět automaticky:stále musíte určit, která skupina dotazů musí být v transakci provedena.
Například poměrně často budete mít před transakcí několik dotazů (před begin
) a dalších pár dotazů po transakci (po buď commit
nebo rollback
) a budete chtít, aby se tyto dotazy provedly bez ohledu na to, co se stalo (nebo ne) v transakci.