Для чего нужен уровень изоляции транзакций Repeatable Read в базах данных?

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

Ответ

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

Проблема (без Repeatable Read):

  1. Транзакция A читает строку, получая значение balance = 100.
  2. Транзакция B обновляет эту строку на balance = 200 и коммитит.
  3. Транзакция A повторно читает ту же строку и видит balance = 200. Это неожиданное изменение внутри транзакции.

Решение с Repeatable Read:

-- Устанавливаем уровень изоляции
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;

-- Первое чтение. СУБД создает снимок данных или блокирует строки.
SELECT balance FROM accounts WHERE id = 1; -- Возвращает 100

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

-- Второе чтение гарантированно вернет те же 100.
SELECT balance FROM accounts WHERE id = 1; -- Все еще 100

COMMIT;

Ключевые детали и отличия в реализациях:

  • Защита: Предотвращает неповторяющееся чтение. В большинстве СУБД (например, PostgreSQL, MySQL с InnoDB) также предотвращает потерянное обновление (lost update).
  • Не защищает от: Фантомного чтения (phantom read) — появления новых строк, удовлетворяющих условию запроса, из-за вставок другими транзакциями. Для защиты от фантомов нужен уровень SERIALIZABLE.
  • Реализация: В PostgreSQL и Oracle используется механизм MVCC (Multi-Version Concurrency Control) с созданием снимков данных на начало транзакции. В SQL Server и MySQL (InnoDB с блокировками) данный уровень активно использует блокировки диапазонов и строк.