Какую аномалию конкурентного доступа предотвращает уровень изоляции Repeatable Read?

Ответ

Уровень изоляции Repeatable Read (повторяемое чтение) решает проблему неповторяющегося чтения (Non-Repeatable Read).

Что такое аномалия Non-Repeatable Read?

Это ситуация, когда в рамках одной транзакции повторное чтение одной и той же строки возвращает разные данные. Это происходит, если другая транзакция успевает изменить или удалить эту строку и зафиксировать (commit) свои изменения между двумя чтениями.

Сценарий аномалии:

  1. Транзакция 1 читает баланс счёта ID=123. Получает balance = 1000.
  2. Транзакция 2 списывает 300 со счёта ID=123 и успешно коммитится. Баланс становится 700.
  3. Транзакция 1 в рамках своих дальнейших операций снова читает баланс счёта ID=123 и внезапно получает balance = 700. Данные, которые она видела в начале, изменились, что может нарушить логику транзакции.

Как Repeatable Read это решает?

Этот уровень изоляции гарантирует, что если транзакция прочитала строку, то любые последующие чтения этой же строки в рамках той же транзакции вернут те же самые значения. База данных, как правило, достигает этого с помощью снимков данных (MVCC) или блокировок на чтение для всех прочитанных строк до конца транзакции.

Что Repeatable Read не решает?

Важно понимать, что этот уровень изоляции не защищает от аномалии фантомного чтения (Phantom Read). Фантом — это ситуация, когда при повторном выполнении запроса с одним и тем же условием WHERE в выборку попадают новые строки, добавленные другой транзакцией. Repeatable Read гарантирует стабильность уже прочитанных строк, но не защищает от появления новых.

Ответ 18+ 🔞

А, слушай, про эти уровни изоляции в базах данных! Ну, это же просто пиздец, как интересно, если вникнуть. Вот смотри, возьмём Repeatable Read — уровень «повторяемого чтения». Он, сука, решает одну конкретную, но охуенно важную проблему, которая называется неповторяющееся чтение (Non-Repeatable Read).

Что это за хуйня такая — Non-Repeatable Read?

Представь себе, ты в рамках одной транзакции два раза читаешь одну и ту же строчку из таблицы, а она тебе, блядь, возвращает разные цифры! Как так-то? А вот так: пока ты там размышляешь, другая транзакция уже успела эту строчку изменить и закоммитить свои правки прямо у тебя под носом.

Живой пример, чтобы мозг не взорвался:

  1. Твоя транзакция (Т1) читает баланс счёта №123. Видит: баланс = 1000 рублей. Ну, вроде всё пиздато.
  2. А какая-то левая транзакция (Т2) в это время списывает с того же счёта 300 рублей и успешно фиксирует это дело. Баланс теперь 700.
  3. Твоя транзакция (Т1), ни о чём не подозревая, снова читает баланс счёта №123. И тут — БАЦ! — получает 700 рублей. Данные нахуй поменялись прямо посреди твоей операции! Вот это и есть «неповторяющееся чтение», ёпта. Логика вся к ебеням может полететь.

И как же Repeatable Read выручает?

А вот как, хитрая жопа! Этот уровень гарантирует тебе одну простую, но офигенную вещь: если ты хоть раз в своей транзакции прочитал какую-то строку, то все последующие чтения этой же самой строки вернут тебе ровно те же самые значения, что и в первый раз. Как будто время для этих данных остановилось. База делает это обычно через снимки данных (этот ваш MVCC) или блокировки, которые держатся до конца твоей транзакции.

Но есть нюанс, блядь!

Запомни раз и навсегда: Repeatable Read — это не серебряная пуля, ёпта! Он НЕ ЗАЩИЩАЕТ от другой аномалии — фантомного чтения (Phantom Read).

Фантом — это когда ты два раза выполняешь один и тот же запрос с условием WHERE, а во второй раз в результатах появляются новые, ебучие строчки, которые кто-то успел добавить параллельно. Repeatable Read держит в ежовых рукавицах только те строки, которые ты уже прочитал, но новые призраки могут материализоваться в любой момент. Вот такая, блядь, магия.