Возможна ли аномалия «неповторяющееся чтение» (Non-Repeatable Read) на уровне изоляции Read Committed?

Ответ

Да, это классическая аномалия для уровня изоляции Read Committed.

  • Что гарантирует Read Committed: Этот уровень изоляции защищает только от "грязного чтения" (Dirty Read). То есть одна транзакция не может прочитать данные, которые были изменены другой транзакцией, но ещё не зафиксированы (COMMIT).

  • Что такое Non-Repeatable Read: Эта аномалия возникает, когда в рамках одной транзакции два последовательных чтения одной и той же строки возвращают разные результаты. Это происходит потому, что между этими чтениями другая транзакция успела изменить эти данные и зафиксировать свои изменения.

Пример в виде временной шкалы:

Представим, что на счете (id=1) изначально 100.

Время Транзакция 1 (Ваша) Транзакция 2 (Параллельная)
T1 BEGIN;
T2 SELECT balance FROM accounts WHERE id = 1;
-- Возвращает 100
T3 BEGIN;
T4 UPDATE accounts SET balance = 200 WHERE id = 1;
T5 COMMIT;
T6 SELECT balance FROM accounts WHERE id = 1;
-- Возвращает 200!
T7 COMMIT;

В момент T6 Транзакция 1 получает другой результат для того же запроса, что и в T2. Это и есть "неповторяющееся чтение".

Для предотвращения этой аномалии необходимо использовать более строгий уровень изоляции, например, Repeatable Read.