Что такое транзакция
Транзакция в контексте баз данных — это последовательность операций с данными, которая выполняется как единое целое: либо все операции успешно применяются, либо ни одна. Основная цель транзакции — обеспечить надежность и согласованность данных даже при сбоях, поэтому она должна удовлетворять принципу ACID.
Как это работает
Транзакция группирует несколько операций (INSERT, UPDATE, DELETE) в один логический блок. Пока транзакция не завершена, изменения видны только внутри нее (в зависимости от уровня изоляции). Завершается транзакция командой COMMIT — фиксацией изменений, или ROLLBACK — откатом к исходному состоянию. Если в процессе выполнения возникает ошибка, транзакция автоматически откатывается, и база данных возвращается к состоянию до начала транзакции.
Принцип ACID расшифровывается так:
- Атомарность (Atomicity) — транзакция выполняется полностью или не выполняется вовсе. Если любая часть не может быть завершена, все действия отменяются.
- Согласованность (Consistency) — транзакция переводит базу из одного согласованного состояния в другое, соблюдая все правила целостности (ограничения, триггеры, внешние ключи).
- Изолированность (Isolation) — параллельные транзакции не видят промежуточных состояний друг друга, что предотвращает «грязное чтение», «неповторяемое чтение» и «фантомные записи».
- Долговечность (Durability) — после COMMIT результаты сохраняются даже при сбое системы (например, отключении питания).
Пример
Классический пример — перевод денег между счетами. Без транзакции при сбое после первого UPDATE баланс первого счета уменьшится, а второго — не увеличится, что нарушит целостность данных.
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 123;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 456;
COMMIT;Если любое из обновлений не выполнится (например, из-за ошибки или сбоя), транзакция будет отменена, и оба счета останутся в исходном состоянии.
Подводные камни
- Длительные транзакции — удерживают блокировки на строках или таблицах, что снижает параллелизм и может привести к взаимоблокировкам (deadlock).
- Уровни изоляции — по умолчанию в MySQL используется REPEATABLE READ, в PostgreSQL — READ COMMITTED. Неправильный выбор уровня может привести к аномалиям чтения.
- Автокоммит — в некоторых СУБД (например, MySQL) каждая отдельная операция автоматически фиксируется, если не открыта явная транзакция. Это важно учитывать при проектировании.
- Не забывайте про ROLLBACK — в коде нужно явно обрабатывать исключения и вызывать откат при ошибке, иначе транзакция может остаться незавершенной.
Когда использовать
Транзакции обязательны для операций, где требуется согласованность нескольких изменений: банковские переводы, обновление остатков на складе, изменение заказа вместе с его позициями, массовое обновление данных. В PHP с PDO транзакция начинается через $pdo->beginTransaction(), завершается $pdo->commit(), а при ошибке — $pdo->rollBack().
Коротко
- Транзакция — это атомарная группа операций, которая либо выполняется целиком, либо откатывается.
- ACID гарантирует атомарность, согласованность, изолированность и долговечность.
- Управление транзакцией: BEGIN, COMMIT, ROLLBACK.
- Используйте транзакции для операций, требующих целостности данных, и следите за длительностью и уровнем изоляции.
