Выбор ответа Senior Транзакции и изоляция обновлено

Фантомы на Repeatable Read в PostgreSQL

Вопрос

В PostgreSQL транзакция на уровне Repeatable Read дважды выполняет SELECT COUNT(*) FROM orders WHERE status = 'new', а между этим другая транзакция вставила и закоммитила новый заказ. Что увидит первая транзакция?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Одинаковое число оба раза: снимок берётся один на всю транзакцию. Repeatable Read в PostgreSQL реализован как snapshot isolation: все запросы транзакции видят снимок на момент её первого запроса, и новые строки в него не попадают.

Варианты ответа

  1. Одинаковое число оба раза: снимок берётся один на всю транзакциюправильный ответ
  2. Второй раз на единицу больше: Repeatable Read не защищает от фантомов
  3. Ошибку сериализации при втором SELECT
  4. Второй SELECT будет ждать, пока закончится вставка

Разбор

Repeatable Read в PostgreSQL реализован как snapshot isolation: все запросы транзакции видят снимок на момент её первого запроса, и новые строки в него не попадают. По стандарту SQL на этом уровне фантомы допустимы, но PostgreSQL даёт более сильную гарантию. Ошибка сериализации бывает при попытке изменить строку, изменённую после снимка, а не при чтении. Читатели в MVCC не ждут.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме