Запобігання подвійним бронюванням: чому системи дають збій, і модель, яка не може

Подвійне бронювання майже ніколи не трапляється тому, що календар «помилився». Воно трапляється тому, що програма перевіряла, чи вільний слот, і резервувала його як два окремі кроки з проміжком між ними — і другий клієнт прослизнув крізь цей проміжок. Закрийте цей проміжок — і решта календаря може бути настільки простою чи складною, наскільки забажаєте. Лишіть його відкритим — і жодна кількість поліровки віджета бронювання не завадить двом людям час від часу опинятися на одному й тому самому кріслі.

Де насправді виникає розрив

Звичайна послідовність, що стоїть майже за кожним бронюванням: перевірити «цей слот усе ще вільний?», отримати «так», а потім записати бронювання. Читання, а потім запис — а між ними, хай навіть на мить, є вікно. Другий запит, що перевіряє той самий слот у цьому вікні, теж бачить «так, усе ще вільно». Обидва тепер вважають, що бронюють вільний слот, бо в момент, коли кожен дивився, так воно й було.

Клацаючи демо в тихий вівторок пополудні, неможливо визначити, чи перевірка й запис під капотом безпечно об'єднані, чи небезпечно розділені, — календар виглядає однаково в обох випадках.

Чому "просто додайте кращий календар" не вирішує проблему

Багато програм для бронювання під капотом — це звичайний конструктор форм, який ніколи не проєктувався на випадок, коли двоє людей претендують на ту саму обмежену річ одночасно. Вибір дати може бути плавним, доступність — виглядати живою, екран підтвердження — охайним, а бек-енд усе одно перевіряє одним читанням і записує окремим, пізнішим записом. Реальний одночасний трафік знаходить цей шов.

Модель, яка справді закриває розрив

Перестаньте розглядати «перевірку» і «резервування» як дві операції: повторно виконайте перевірку доступності й запишіть бронювання всередині однієї транзакції бази даних, яка блокує рядки для цього слота. Який би запит не прийшов першим, він завершує свою перевірку й запис без переривань; другий чекає своєї черги, а потім перевіряє знову вже за новою реальністю. Не лишається вікна, в якому можна діяти за застарілою інформацією «ще доступно» — порядок забезпечує база даних, а не код застосунку, що сподівається на відсутність гонок.
Бронювання та розклад в адмінпанелі Olmira

Що насправді відбувається, коли двоє одночасно натискають «забронювати»

1

Обидва запити надходять майже одночасно

2

Один запит першим отримує блокування

3

Перший запит одночасно перевіряє наново й записує

4

Другий запит наново звіряється з новою реальністю

5

Другий клієнт дізнається про це одразу

Як це влаштовано в Olmira

Механізм бронювання Olmira виконує повторну перевірку доступності та запис броні одним кроком, усередині однієї заблокованої транзакції бази даних, — тому коли два клієнти одночасно націлюються на той самий слот, одна бронь фіксується, а другому, ще до того як зрушать будь-які гроші, повідомляють, що час щойно зайняли. Те саме блокування охоплює й сам ресурс, а не лише послугу, що продається, тож дві різні послуги, які використовують один кабінет або одного працівника, теж не можуть непомітно зайняти його двічі. Окремий, простіший запобіжник ловить поширенішу помилку — той самий клієнт двічі натискає «забронювати» — і просить його підтвердити, замість того щоб мовчки створити два записи. Як усе це поєднується, дивіться на сторінці бронювання.

Схожі посібники

Персонал, приміщення, обладнання

Неявки: що справді змінює цифру

Календар, який чесно показує, що вільно

Реальні слоти, перевірені та заблоковані в момент бронювання, — а не здогад за тим, що сторінка завантажила секунду тому.