Транзакции и ACID

Объединяем несколько операций в одно неделимое целое и понимаем, что такое ACID.

Транзакция — группа операций, которые выполняются как единое целое: либо применяются все, либо не применяется ни одна.

Классический пример: перевод денег

Перевод со счёта на счёт — это два действия: списать у одного и зачислить другому. Если между ними случится сбой, деньги «испарятся»: списано, но не зачислено. Транзакция гарантирует, что либо оба действия выполнятся, либо ни одно.

BEGIN;                                          -- начали транзакцию

UPDATE accounts SET balance = balance - 1000 WHERE id = 1;  -- списали
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;  -- зачислили

COMMIT;                                         -- зафиксировали оба изменения

Между BEGIN и COMMIT изменения видны только вам. После COMMIT они становятся постоянными и видны всем. Если до COMMIT что-то пошло не так, мы откатываемся.

ROLLBACK — отмена

ROLLBACK отменяет все изменения с начала транзакции, будто их не было. Это страховка от ошибок.

BEGIN;
DELETE FROM orders WHERE created_at < '2020-01-01';
-- Ой, удалили слишком много! Откатываем:
ROLLBACK;
-- Все удалённые строки вернулись на место

Принципы ACID

Надёжность транзакций описывают четырьмя свойствами — аббревиатура ACID. PostgreSQL соблюдает их по умолчанию.

СвойствоЧто гарантирует
Atomicity (атомарность)транзакция применяется целиком или не применяется вовсе
Consistency (согласованность)база переходит из одного корректного состояния в другое, ограничения соблюдаются
Isolation (изоляция)параллельные транзакции не мешают друг другу
Durability (устойчивость)после COMMIT данные сохранены, даже если сервер тут же отключится

Точки сохранения (SAVEPOINT)

Внутри транзакции можно ставить промежуточные метки и откатываться частично, не отменяя всю транзакцию.

BEGIN;
INSERT INTO logs (msg) VALUES ('шаг 1');
SAVEPOINT after_first;            -- метка
INSERT INTO logs (msg) VALUES ('шаг 2');
ROLLBACK TO after_first;          -- отменили только шаг 2
COMMIT;                           -- шаг 1 сохранён, шаг 2 — нет

Когда транзакции особенно нужны

  • Любые переводы и платежи — деньги нельзя потерять.
  • Создание связанных записей: заказ + позиции заказа должны появиться вместе.
  • Массовые обновления, где важна «всё или ничего».

В обычной автокоммит-сессии каждая отдельная команда — это уже мини-транзакция. Явные BEGIN/COMMIT нужны, когда несколько команд обязаны выполниться как одно целое.

Итог

  • Транзакция (BEGIN ... COMMIT) делает группу операций неделимой: всё или ничего.
  • ROLLBACK отменяет изменения с начала транзакции; SAVEPOINT позволяет откатиться частично.
  • ACID — атомарность, согласованность, изоляция, устойчивость; PostgreSQL соблюдает их по умолчанию.
Проверьте себя
1. Что гарантирует атомарность (Atomicity) транзакции?
AЧто транзакция выполнится мгновенно
BЧто применятся либо все операции транзакции, либо ни одной
CЧто данные зашифрованы
DЧто транзакция не использует индексы
2. Что делает команда ROLLBACK?
AФиксирует изменения навсегда
BОтменяет все изменения с начала транзакции
CУдаляет таблицу
DСоздаёт точку сохранения
3. Какое свойство ACID гарантирует, что после COMMIT данные не потеряются при сбое сервера?
AAtomicity
BConsistency
CIsolation
DDurability
Поддержать проект