← Все работы
OmnibusЖивое демоБронирование мест · командный проект на ČVUT FEL

Два пассажира, одно место, никаких двойных броней

Система бронирования автобусов с живой схемой мест. Когда двое хватают одно место в один момент, достаётся оно только одному.

Командный семестровый проект на ČVUT FEL, авторы — Mykhailo Plokhin и Ivan Shestachenko. Это демо, а не настоящий перевозчик.

Java · Spring Boot · PostgreSQL · React · Docker · k3s

Главная Omnibus на телефоне: поиск рейса и популярные маршруты из Чехии
Omnibus на телефоне: детали поездки по маршруту 501 из Праги в Брно

Задача

Системы бронирования ломаются ровно тогда, когда двое хотят одно и то же одновременно — а это и есть момент, когда бизнес зарабатывает.

  • Если приложение сначала читает место, а потом записывает, два запроса могут оба увидеть его свободным и оба его забронировать.
  • Овербукинг часто чинят задним числом ночным скриптом и извинениями, вместо того чтобы сделать его невозможным.
  • Пассажиру и диспетчеру нужны разные права, а не один эндпоинт за разными экранами.

Как устроено

Бронированиями владеет один сервис, и больше никто не пишет места. Спорное место проходит через одну короткую транзакцию с блокировкой строки.

Схема мест Omnibus на телефоне: свободные, занятые и панорамные места по рядам
ABждётзанято

Пассажир A бронирует место 12. База блокирует эту строку.

Пассажир B в тот же момент просит место 12 и ждёт, пока блокировка снимется.

Бронь A сохраняется. B получает «место занято», а не двойную бронь.

токенброньFOR UPDATEIngressSpring REST APIРоли · JWTСервис бронейМаршруты и автопаркPostgreSQL · блокировки

Ключевые решения

Каждое решение и альтернатива, которую оно обошло.

Блокировать строку спорного места

Второй запрос ждёт, а не перезаписывает, и ждёт недолго: удержание места — единственная работа внутри транзакции. Альтернативой были оптимистичные повторы; на полном рейсе они превращаются в лавину повторов.

Один путь записи для броней

Расписание, схема мест и диспетчер только читают. С одним писателем правило «одно место — один пассажир» система может реально проверить.

Роли проверяются на эндпоинте

Spring Security определяет роль до обработчика, поэтому действие диспетчера недоступно с URL пассажира.

Цифры

Omnibus — университетский проект с живым демо, а не коммерческий сервис. «Проверено» значит проверено в коде; «цель» — на что система рассчитана.

ПоказательЧто значит
ZeroДвойные брониЦель системы: второго писателя отклоняет база, а не ночной скрипт потом.Цель
FOR UPDATEБлокировка местаПессимистическая блокировка строки в запросе места (BookedSegmentRepository).Проверено
k3sГде работаетКонтейнеры на кластере k3s — адрес по ссылке на этой странице.Проверено
Цель
— На что рассчитана система — не измеренный результат
Проверено
— Проверено в коде или на рабочей версии

Нужно что-то похожее?

Опишите задачу в паре строк. Ответит человек из команды.

Обсудить проект