← Назад к вопросам

Как расшифровывается ACID?

1.8 Middle🔥 131 комментариев
#SQL и базы данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ACID: Четыре основы надёжных баз данных

ACID это аббревиатура четырёх фундаментальных свойств транзакций в системах управления базами данных, обеспечивающих целостность и надёжность данных. Понимание ACID критично для любого Data Engineer.

A — Atomicity (Атомарность)

Транзакция либо полностью выполняется, либо полностью откатывается. Нет промежуточных состояний.

Пример — перевод денег между счётами:

BEGIN TRANSACTION;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;  -- Снять с первого
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;  -- Положить на второе
COMMIT;

Если произойдёт сбой между двумя UPDATE:

  • Либо оба UPDATE выполнятся (деньги переведены)
  • Либо оба откатятся (деньги остались как были)
  • Никогда не произойдёт ситуация, когда снято со счёта 1, но не положено на счёт 2

Реальный сценарий:

BEGIN TRANSACTION;
  INSERT INTO transactions (from_id, to_id, amount) VALUES (1, 2, 100);
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
  -- Если здесь сбой БД, всё откатится
COMMIT;  -- Либо всё успешно сохранится

C — Consistency (Консистентность)

База данных переходит из одного консистентного состояния в другое. Все правила и ограничения (constraints) остаются выполненными.

Пример с бизнес-правилом:

CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    age INT CHECK (age >= 18),  -- Ограничение консистентности
    account_balance DECIMAL >= 0  -- Баланс не может быть отрицательным
);

-- Попытка нарушить консистентность
INSERT INTO users (id, email, age, account_balance) 
VALUES (1, "john@example.com", 15, -100);  -- ОШИБКА!
-- Возраст < 18 и баланс < 0 нарушают constraints

-- Правильная вставка
INSERT INTO users (id, email, age, account_balance) 
VALUES (1, "john@example.com", 25, 0);  -- OK

Пример с внешним ключом:

CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT NOT NULL,
    amount DECIMAL,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Нельзя создать заказ с несуществующим пользователем
INSERT INTO orders (id, user_id, amount) 
VALUES (1, 999, 100);  -- ОШИБКА! user_id=999 не существует

Транзакция гарантирует, что после COMMIT база будет в консистентном состоянии.

I — Isolation (Изоляция)

Одновременные транзакции не влияют друг на друга. Каждая видит данные, как если бы она была единственной.

Проблема без изоляции (Dirty Read):

Транзакция 1:                     Транзакция 2:
  BEGIN;                         
  UPDATE balance SET x = 100     
                                   BEGIN;
                                   SELECT balance;  -- Вывод: 100 (грязное чтение!)
  ROLLBACK;  -- Откат!
                                   SELECT balance;  -- Вывод: 50 (было изначально)

С ISOLATION LEVEL = SERIALIZABLE (максимальная изоляция):

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

BEGIN;
  SELECT balance FROM accounts WHERE id = 1;  -- Вид: 50
  -- Параллельная транзакция не может менять этот счёт
COMMIT;

Уровни изоляции (от слабого к сильному):

READ UNCOMMITTED    - минимальная изоляция, максимальная скорость
READ COMMITTED      - стандартный уровень
REPEATABLE READ     - средняя изоляция
SERIALIZABLE        - максимальная изоляция, минимальная скорость

D — Durability (Долговечность)

Если транзакция выполнена (COMMIT), данные остаются в базе даже при сбое питания, краша системы или дисковых ошибок.

Механизм в современных БД:

1. Транзакция выполняется в памяти (буфер)
2. Изменения записываются в WAL (Write-Ahead Log) на диск
3. COMMIT подтверждает: данные безопасно на диске
4. Данные затем записываются в основные файлы БД
5. При сбое БД восстанавливается из WAL

Пример в PostgreSQL:

BEGIN;
  INSERT INTO logs (message) VALUES ("Important data");
  UPDATE balance SET x = 100;  -- Оба в памяти
COMMIT;  -- Гарантия: данные на диске, безопасны
-- Даже если сейчас выключится питание, данные останутся

Сравнение ACID свойств

СвойствоГарантияПример нарушения
AtomicityВсё или ничегоПоловина обновлений, половина откатилась
ConsistencyПравила сохраняютсяОтрицательный баланс при CHECK
IsolationТранзакции независимыОдна видит незакоммиченные изменения другой
DurabilityДанные постоянныПосле выключения питания данные потеряны

ACID в контексте Data Engineering

Когда ACID критичны:

  • Финансовые системы (потеря деньги — недопустимо)
  • Критичные данные (инвентарь, заказы)
  • Системы с высокими требованиями к надёжности

Когда ACID менее критичны:

  • Аналитические БД (редко обновляются)
  • Log-based системы (потеря одного лога — не катастрофа)
  • Big Data системы, где ApacheHadoop отказывается от полного ACID

Базы данных и ACID

Полная поддержка ACID:

  • PostgreSQL (отличный ACID)
  • MySQL с InnoDB (полный ACID)
  • SQLite (ACID на одной машине)
  • Oracle Database

Частичная поддержка (BASE модель):

  • MongoDB (в некоторых версиях) — многодокументные транзакции
  • DynamoDB — условные операции вместо транзакций
  • Cassandra — конечная консистентность вместо строгой ACID

Заключение

ACID представляет четыре столпа надёжности баз данных:

  • A: либо выполнится всё, либо ничего
  • C: правила и ограничения всегда соблюдены
  • I: одновременные операции не мешают друг другу
  • D: коммиченные данные永远 остаются в базе

Для Data Engineer важно выбирать БД в соответствии с требованиями ACID конкретного проекта.