Что означает уровень изоляции транзакций REPEATABLE_READ?

«Что означает уровень изоляции транзакций REPEATABLE_READ?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

REPEATABLE_READ — это уровень изоляции транзакций, который гарантирует, что если транзакция повторно читает одни и те же данные, она получит идентичный результат. Он предотвращает Dirty Reads и Non-repeatable Reads, но может допускать Phantom Reads.

Характеристики и проблемы:

  • Предотвращает:
    • Dirty Read.
    • Non-repeatable Read.
  • Допускает:
    • Phantom Read: Транзакция может увидеть новые строки, добавленные другими зафиксированными транзакциями после ее начала.

Как это работает: Транзакция "видит" снимок данных (snapshot) на момент своего первого оператора чтения. Все последующие чтения в рамках этой транзакции будут возвращать данные из этого снимка, даже если другие транзакции уже изменили и зафиксировали исходные данные.

Практический пример:

-- Транзакция 1 (уровень REPEATABLE_READ)
BEGIN TRANSACTION;
SELECT COUNT(*) FROM users WHERE active = true; -- Возвращает 5

-- Транзакция 2
BEGIN TRANSACTION;
INSERT INTO users (name, active) VALUES ('NewUser', true);
COMMIT;

-- Транзакция 1 (продолжение)
SELECT COUNT(*) FROM users WHERE active = true; -- Все еще возвращает 5 (Phantom Read предотвращен в некоторых СУБД)
UPDATE users SET active = false WHERE active = true; -- Может заблокировать больше строк, чем ожидалось
COMMIT;

Важно: В MySQL (с движком InnoDB) и некоторых других СУБД реализация REPEATABLE_READ с использованием механизма snapshot также предотвращает Phantom Reads за счет использования next-key locks. В PostgreSQL и Oracle этот уровень эквивалентен SERIALIZABLE в смысле snapshot изоляции.