Фотография
нажмите — покажем
нажмите — покажем
Два клиента одновременно бронируют один номер. Как не продать его дважды?
Обычная проверка «свободен ли номер?» может пропустить оба запроса: каждый успеет увидеть свободное время до сохранения чужой брони.
В PostgreSQL можно запретить пересечения прямо в базе:
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE TABLE bookings (
room_id INT NOT NULL,
starts_at TIMESTAMPTZ NOT NULL,
ends_at TIMESTAMPTZ NOT NULL,
CHECK (ends_at > starts_at),
EXCLUDE USING gist (
room_id WITH =,
tstzrange(starts_at, ends_at, '[)') WITH &&
)
);
Как это работает:
• room_id WITH = — проверяем брони одного номера.
• WITH && — запрещаем пересечение временных интервалов.
• '[)' — начало включено, конец исключён. Брони 10:00–11:00 и 11:00–12:00 допустимы.
• CHECK — окончание должно быть позже начала.
Ограничение действует и при одновременных запросах. Две конфликтующие брони сохранить не получится: приложение должно обработать ошибку и сообщить, что время уже занято.
Подходит для гостиниц, переговорных, аренды оборудования и записи к специалистам.
44 · 3.7K ·