Ответ
Repeatable Read — это уровень изоляции, гарантирующий, что данные, прочитанные в рамках одной транзакции, не будут изменены другими зафиксированными транзакциями до её завершения. Это предотвращает аномалию неповторяющегося чтения.
Практический пример (аномалия «фантомное чтение»):
Две транзакции работают с таблицей orders, где статус processed = false.
-- Транзакция 1 (T1) - Отчет по необработанным заказам
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT COUNT(*) FROM orders WHERE processed = false; -- Результат: 5
-- Транзакция 2 (T2) - Параллельная обработка
BEGIN;
UPDATE orders SET processed = true WHERE id = 1;
COMMIT;
-- T1 повторяет чтение. При Repeatable Read видит те же 5 строк.
-- Фантомное чтение здесь НЕ предотвращается.
SELECT COUNT(*) FROM orders WHERE processed = false; -- Всё ещё 5 (старые данные)
-- Однако, если T2 вставит НОВУЮ строку...
-- (В параллельной сессии)
BEGIN;
INSERT INTO orders (id, processed) VALUES (100, false);
COMMIT;
-- ...то T1 при повторном запросе может её увидеть (фантом).
SELECT COUNT(*) FROM orders WHERE processed = false; -- Может стать 6 (фантомная строка)
COMMIT;
Ключевой момент: REPEATABLE READ гарантирует, что уже прочитанные строки не изменятся, но не блокирует вставку новых строк (фантомов), в отличие от SERIALIZABLE. В некоторых СУБД (например, PostgreSQL) для предотвращения фантомов на этом уровне используются блокировки диапазонов.