Идея, которую я обычно использую при работе с транзакциями, выглядит следующим образом (полупсевдокод) :
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 (Exception $e) {
// An exception has been thrown
// We must rollback the transaction
$db->rollback();
}
Обратите внимание, что с этой идеей, если запрос не выполняется, должно быть сгенерировано исключение:
- PDO может сделать это, в зависимости от того, как вы его настроили
- в противном случае, с некоторым другим API, вам может потребоваться проверить результат функции, используемой для выполнения запроса, и сгенерировать исключение самостоятельно.
К сожалению, в этом нет никакой магии. Вы не можете просто поместить инструкцию куда-нибудь и сделать транзакции автоматически: вам все равно нужно указать, какая группа запросов должна быть выполнена в транзакции.
Например, довольно часто у вас будет пара запросов до транзакции (до begin
) и еще пара запросов после транзакции (после commit
или rollback
) и вы хотите, чтобы эти запросы выполнялись независимо от того, что произошло (или нет) в транзакции.