Ответ вслух Middle Консистентность и CAP обновлено

Защита от двойного бронирования

Вопрос

Как не продать одно место в кинотеатре двум покупателям, которые нажали «купить» одновременно?

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Источник истины одна БД, и защиту делаю на её уровне. Самое простое: таблица билетов с уникальным ключом (сеанс, место), второй INSERT получит ошибку уникальности.

Что должно прозвучать в ответе

  • Ограничение уникальности на (сеанс, место) в БД

  • Или условное обновление: UPDATE ... WHERE status = свободно, проверка числа затронутых строк

  • Временный холд места с истечением на время оплаты

  • Пессимистичная блокировка SELECT FOR UPDATE как вариант при низкой конкуренции

  • Распределённый лок в Redis только с пониманием его ограничений

Что могут спросить следом

  • Что делать, если оплата не пришла за 10 минут?
  • Чем опасен лок в Redis?

Разбор

Источник истины одна БД, и защиту делаю на её уровне. Самое простое: таблица билетов с уникальным ключом (сеанс, место), второй INSERT получит ошибку уникальности. Либо места заранее заведены, и бронирование это UPDATE seats SET status = 'held', hold_until = now() + interval '10 minutes' WHERE id = ... AND status = 'free': если затронуто 0 строк, место уже занято. Холд истекает, если оплата не пришла, фоновая задача или условие в запросе освобождают место. Распределённый лок в Redis добавляет точку отказа и при истечении лока во время паузы процесса не спасает, поэтому финальную проверку всё равно делает БД.

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

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