> Какие особенности транзакций существуют (PHP)

Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: vanta

Стек: PHP

> Пример ответа

Короткий ответ

Транзакции в БД обладают свойствами ACID: атомарность, согласованность, изоляция и долговечность. Ключевые особенности - атомарность (все или ничего), уровни изоляции (read uncommitted, read committed, repeatable read, serializable), обработка конкурентного доступа через блокировки и MVCC, а также управление через commit и rollback. В PHP с PDO транзакции включаются через beginTransaction(), фиксируются commit() и откатываются rollBack().

Подробное объяснение

Транзакция - это логическая единица работы, которая либо выполняется полностью, либо не выполняется вовсе. Основные особенности:

  • Атомарность: все операции внутри транзакции применяются как единое целое. При ошибке любая операция откатывается.
  • Согласованность: транзакция переводит БД из одного согласованного состояния в другое, сохраняя инварианты (constraints, foreign keys).
  • Изоляция: параллельные транзакции не должны влиять друг на друга. Уровни изоляции определяют, насколько сильно они изолированы. Проблемы: dirty read, non-repeatable read, phantom read.
  • Долговечность: после commit данные сохраняются даже при сбое системы.

В MySQL (InnoDB) по умолчанию используется repeatable read, в PostgreSQL - read committed. Механизмы реализации: pessimistic locking (блокировки строк/таблиц) и optimistic concurrency control (MVCC - snapshot изоляция).

Особенности в PHP: PDO поддерживает транзакции, но важно помнить, что вложенные транзакции не поддерживаются нативно - нужны savepoints. Также нужно учитывать, что DDL-операции (ALTER, CREATE) в MySQL вызывают неявный commit.

На практике

При работе с PHP и БД важно:

  • Всегда оборачивать несколько связанных запросов в транзакцию, если они должны быть атомарными (например, перевод денег: списание и зачисление).
  • Выбирать уровень изоляции осознанно: для большинства финансовых операций - serializable или repeatable read, для логов - read committed.
  • Использовать retry-логику при deadlock'ах (MySQL error 1213) - повторять транзакцию.
  • Не держать транзакции открытыми долго - это блокирует строки и снижает конкурентность.
  • В PHP с PDO проверять, что соединение не в режиме autocommit, если нужна транзакция.

Пример кода

PHP
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$pdo->beginTransaction();
// списание со счета отправителя
$stmt = $pdo->prepare('UPDATE accounts SET balance = balance - :amount WHERE id = :from');
$stmt->execute([':amount' => 100, ':from' => 1]);
// зачисление на счет получателя
$stmt = $pdo->prepare('UPDATE accounts SET balance = balance + :amount WHERE id = :to');
$stmt->execute([':amount' => 100, ':to' => 2]);
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
// логирование ошибки, повторная попытка при deadlock
throw $e;
}

Как отвечать на собеседовании

Начните с определения ACID, затем перечислите уровни изоляции и связанные с ними аномалии. Упомяните разницу между блокировками и MVCC. Приведите пример из практики, где транзакция критична (перевод денег, заказ с несколькими позициями). Покажите понимание trade-off: более высокий уровень изоляции - ниже конкурентность. Если спросят про PHP - расскажите про PDO, savepoints, неявный commit при DDL.

Что проверяет интервьюер

  • Понимание фундаментальных свойств транзакций, а не заученных определений.
  • Умение объяснить, как уровни изоляции влияют на реальные сценарии.
  • Знание механизмов реализации (блокировки, MVCC) и их ограничений.
  • Практический опыт: обработка ошибок, deadlock'и, производительность.
  • Способность связать теорию с конкретным стеком (PHP, PDO, MySQL/PostgreSQL).

Типичные ошибки

  • Путаница между dirty read и non-repeatable read.
  • Утверждение, что транзакции решают все проблемы конкурентности - на самом деле они лишь изолируют, а конфликты нужно обрабатывать.
  • Игнорирование неявного commit при DDL в MySQL.
  • Отсутствие обработки исключений при commit - commit тоже может упасть.
  • Использование транзакций для одиночных запросов без необходимости - это лишние накладные расходы.
  • Забывают про savepoints при вложенных транзакциях в PDO.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью