Что такое транзакция при работе с базами данных в PHP?

«Что такое транзакция при работе с базами данных в PHP?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Транзакция — это группа SQL-запросов, которая выполняется как единая, атомарная операция. Она следует принципам ACID. Если все запросы выполняются успешно, изменения фиксируются (commit). Если возникает ошибка на любом этапе, все уже выполненные в рамках этой транзакции изменения откатываются (rollback), оставляя базу данных в согласованном состоянии.

Практический пример с PDO (перевод средств между счетами):

$pdo = new PDO('mysql:host=localhost;dbname=bank', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    // Начало транзакции
    $pdo->beginTransaction();

    // Списываем сумму со счета отправителя
    $stmt1 = $pdo->prepare("UPDATE accounts SET balance = balance - :amount WHERE id = :from_id");
    $stmt1->execute([':amount' => 100, ':from_id' => 1]);

    // Зачисляем сумму на счет получателя
    $stmt2 = $pdo->prepare("UPDATE accounts SET balance = balance + :amount WHERE id = :to_id");
    $stmt2->execute([':amount' => 100, ':to_id' => 2]);

    // Фиксируем изменения, если все прошло успешно
    $pdo->commit();
    echo "Transfer successful";
} catch (PDOException $e) {
    // В случае любой ошибки откатываем все изменения
    $pdo->rollBack();
    echo "Transfer failed: " . $e->getMessage();
}

Ключевые моменты для PHP-разработчика:

  1. Изоляция через beginTransaction(): Запросы внутри транзакции изолированы от других соединений до момента commit() (уровень изоляции зависит от настройки СУБД).
  2. Обязательная обработка ошибок: Транзакции требуют использования try...catch для гарантированного вызова rollBack() при исключении.
  3. Поддержка драйверов: Транзакции работают с PDO для всех поддерживающих их СУБД (MySQL/InnoDB, PostgreSQL) и с расширением mysqli.
  4. Вложенные транзакции: PDO может эмулировать вложенные транзакции через SAVEPOINT, но реальная вложенность поддерживается на уровне самой СУБД (например, в PostgreSQL).