Что гарантирует уровень изоляции транзакций Repeatable Read?

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

Ответ

Уровень изоляции Repeatable Read гарантирует, что в рамках одной транзакции многократное чтение одних и тех же строк вернет идентичные данные. Он предотвращает неповторяющееся чтение (non-repeatable read), но, согласно стандарту SQL, может допускать фантомное чтение (phantom read).

Что предотвращается:

  • Грязное чтение (Dirty Read): Невозможно.
  • Неповторяющееся чтение (Non-Repeatable Read): Невозможно. Если транзакция дважды прочитала строку, другая транзакция не сможет изменить или удалить эту строку до ее завершения.
  • Фантомное чтение (Phantom Read): Возможно. Другая транзакция может добавить новые строки, соответствующие условиям WHERE.

Механизм реализации: Как правило, достигается за счет блокировок на уровне строк (shared locks) на все прочитанные строки до конца транзакции.

Пример сценария (PostgreSQL/SQL):

-- Сессия 1
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE id = 1; -- Чтение 1: баланс = 100

-- Сессия 2 (параллельно)
UPDATE accounts SET balance = 200 WHERE id = 1; -- Будет заблокирована до коммита Сессии 1!
COMMIT;

-- Сессия 1
SELECT balance FROM accounts WHERE id = 1; -- Чтение 2: баланс ВСЕ ЕЩЕ = 100 (гарантия!)
COMMIT;
-- После коммита Сессии 1, UPDATE из Сессии 2 выполнится.

Когда использовать? Для операций, где критически важна согласованность уже прочитанных данных (например, проверка баланса перед списанием и самим списанием). В PostgreSQL и некоторых других СУБД REPEATABLE READ также предотвращает фантомы за счет snapshot-изоляции.