Фантомы на Repeatable Read в PostgreSQL
Вопрос
В PostgreSQL транзакция на уровне Repeatable Read дважды выполняет SELECT COUNT(*) FROM orders WHERE status = 'new', а между этим другая транзакция вставила и закоммитила новый заказ. Что увидит первая транзакция?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Одинаковое число оба раза: снимок берётся один на всю транзакциюправильный ответ
- Второй раз на единицу больше: Repeatable Read не защищает от фантомов
- Ошибку сериализации при втором SELECT
- Второй SELECT будет ждать, пока закончится вставка
Разбор
Repeatable Read в PostgreSQL реализован как snapshot isolation: все запросы транзакции видят снимок на момент её первого запроса, и новые строки в него не попадают. По стандарту SQL на этом уровне фантомы допустимы, но PostgreSQL даёт более сильную гарантию. Ошибка сериализации бывает при попытке изменить строку, изменённую после снимка, а не при чтении. Читатели в MVCC не ждут.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Транзакции и изоляция»
- Advisory-блокировки в PostgreSQL
- Как избежать deadlock при переводах
- Взаимоблокировки: как ловить и предотвращать
- Долгая транзакция и раздувание таблиц
- MVCC и VACUUM в PostgreSQL
- VACUUM или VACUUM FULL на проде
- Зачем нужна заморозка и что такое wraparound
- Что делает PostgreSQL при deadlock