Идеята, която обикновено използвам, когато работя с транзакции, изглежда така (полупсевдокод) :
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
}
Обърнете внимание, че с тази идея, ако заявка не успее, трябва да бъде изведено изключение:
- PDO може да направи това, в зависимост от това как го конфигурирате
- Вижте
PDO::setAttribute
- и
PDO::ATTR_ERRMODE
иPDO::ERRMODE_EXCEPTION
- Вижте
- в противен случай, с някакъв друг API, може да се наложи да тествате резултата от функцията, използвана за изпълнение на заявка, и сами да хвърлите изключение.
За съжаление, няма замесена магия. Не можете просто да поставите инструкция някъде и транзакциите да се извършват автоматично:все пак трябва да посочите коя група заявки трябва да се изпълни в транзакция.
Например, доста често ще имате няколко заявки преди транзакцията (преди begin
) и още няколко заявки след транзакцията (след или след commit
или rollback
) и ще искате тези заявки да бъдат изпълнени, независимо какво се е случило (или не) в транзакцията.