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

Что такое изоляция в ACID?

1.7 Middle🔥 161 комментариев
#Базы данных и SQL

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

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

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

Изоляция в ACID

Изоляция (Isolation) — это одно из четырёх ключевых свойств ACID-транзакций, которое обеспечивает независимое выполнение одновременных транзакций. Другими словами, изоляция гарантирует, что одновременно выполняемые транзакции не мешают друг другу и каждая видит консистентное состояние данных.

Основная идея

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

Уровни изоляции

С каждого уровня повышается степень изоляции, но снижается конкурентность:

1. READ UNCOMMITTED — самый низкий уровень. Транзакция может читать незафиксированные изменения других транзакций (грязное чтение). Почти не используется в боевых системах.

2. READ COMMITTED — транзакция видит только зафиксированные данные. Предотвращает грязное чтение, но допускает неповторяемое чтение (при повторном запросе получаются другие значения).

3. REPEATABLE READ — гарантирует, что прочитанные данные не изменятся в течение транзакции. Но возможны фантомные строки (при повторном запросе с условием появляются новые строки).

4. SERIALIZABLE — самый строгий уровень. Транзакции выполняются так, как будто последовательно одна за другой. Полностью предотвращает все аномалии, но сильно снижает производительность.

Проблемы без изоляции

// Проблема: грязное чтение
Transaction T1: UPDATE accounts SET balance = 1000 WHERE id = 1;
Transaction T2: SELECT balance FROM accounts WHERE id = 1; // видит 1000
Transaction T1: ROLLBACK; // откат!
// T2 прочитала данные, которые не были зафиксированы

// Проблема: неповторяемое чтение
Transaction T1: SELECT salary FROM employees WHERE id = 5; // получил 50000
Transaction T2: UPDATE employees SET salary = 60000 WHERE id = 5; COMMIT;
Transaction T1: SELECT salary FROM employees WHERE id = 5; // получил 60000

В контексте Java и БД

В Java при работе с базами данных уровень изоляции задаётся через JDBC или JPA:

Connection conn = DriverManager.getConnection(url, user, pass);
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

Statement stmt = conn.createStatement();
stmt.executeQuery("SELECT * FROM accounts WHERE id = 1");
conn.commit();

Для Spring Data JPA:

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
    Account from = accountRepository.findById(fromId).orElseThrow();
    Account to = accountRepository.findById(toId).orElseThrow();
    
    from.setBalance(from.getBalance().subtract(amount));
    to.setBalance(to.getBalance().add(amount));
    
    accountRepository.save(from);
    accountRepository.save(to);
}

Выбор уровня изоляции

В большинстве современных систем используется REPEATABLE READ или READ COMMITTED — это оптимальный баланс между безопасностью данных и производительностью. SERIALIZABLE используется редко из-за его влияния на производительность.