В чем разница уровней изоляции транзакций read committed и repeatable read
Что проверяют
Знаете ли вы, какую конкретную аномалию снимает переход между этими двумя уровнями.
Как отвечать
READ COMMITTED (значение по умолчанию в PostgreSQL): каждый запрос внутри транзакции видит свой снимок данных на момент своего начала. Грязного чтения нет, но два одинаковых SELECT в одной транзакции могут вернуть разное, если между ними кто-то зафиксировал изменения. Это неповторяемое чтение, и вместе с ним возможны фантомы.
REPEATABLE READ: снимок делается один раз, на момент начала транзакции, и все запросы видят его. Повторное чтение всегда даёт то же самое. В PostgreSQL благодаря MVCC на этом уровне пропадают и фантомы, хотя стандарт этого не требует, а в MySQL для фантомов дополнительно используются gap-блокировки.
Практическая разница: READ COMMITTED подходит обычным операциям, где важна свежесть данных. REPEATABLE READ нужен, когда транзакция делает несколько чтений и должна видеть согласованную картину: отчёт, сверка, перенос данных.
Цена: на REPEATABLE READ PostgreSQL может отклонить фиксацию с ошибкой сериализации, если данные изменились под ногами. Приложение обязано уметь повторить транзакцию, иначе строгий уровень превращается в случайные ошибки.
Важно добавить, что от потерянного обновления ни один из уровней сам по себе не спасает при схеме «прочитал, посчитал, записал». Для этого нужны SELECT ... FOR UPDATE или версия строки.
Где спотыкаются
Не могут назвать конкретную аномалию, которую снимает переход.
Считают, что REPEATABLE READ блокирует данные: он даёт снимок, а не блокировку.
Переключают уровень без обработки ошибки сериализации.
Полагают, что уровень изоляции решает проблему потерянного обновления.