Возможно ли состояние гонки и как его избежать?

Здравствуйте, я новичок в node.js, до этого я писала код веб-приложений на php. Собственно, насколько я знаю код в node.js выполняется асинхронно и у меня появился такой вопрос:
Есть к примеру страница с местами в кинозале, или с доступными местами в самолёте, пользователь может произвольно выбрать незанятое место, либо нажать кнопку выбрать "рандомно".
На сервере есть цепочка обработчиков, но в случае с "случайным" вариантом, добавляется промежуточный обработчик который смотрит занятые места в базе и на основе полученных данных выбирает незанятое и передаёт дальше по цепочке.
Если пользователь №1 нажал кнопку выбрать случайно, а пользователь №2 выбрал произвольное место ПОСЛЕ пользователя №1(к примеру номер 10) и у пользователя №1 случайно выпало место 10, есть ли шанс того что пользователь №2 займёт место быстрее чем №1?
  • Вопрос задан
  • 881 просмотр
Пригласить эксперта
Ответы на вопрос 2
MarcusAurelius
@MarcusAurelius Куратор тега Node.js
автор Impress Application Server для Node.js
Смотря где на сервере хранятся данные о занятых местах и как происходит бронирование. Например, если таблица мест в базе, и для занятия следующего случайного из ноды нужно сделать два запроса:
1) Выбрать случайное
2) Пометить выбранное занятым
То между этими запросами может втиснуться запрос от другого пользователя и все испортит. А вот если эта операция атомарная, т.е. отправляется в СУБД и 1 и 2 вместе и возвращается номер случайного места, то все будет ок. Но лучше всего в этой ситуации, сразу забрать все места в память в массив, один раз их там перемешать случайным образом. arr.sort(function () { return Math.random() - 0.5; }); и потом брать по запросу один arr.pop(); и если сервер в одном потоке, то это гарантирует, что ни кто не возьмет один и тот же. А вот сохранять в базу можно уже в отложенном режиме. Если поток запросов очень большой, то сложнее, тут уже одним потоком не обойтись, тут нужно делить массив на блоки и держать каждый блок в отдельном процессе или отдельном сервере.
Ответ написан
Комментировать
@sergeystepanov1988
Если пользователь №1 нажимает на кнопку "Выбрать случайно" и его запрос еще выполняется, то он не получит еще никакого места. Если в это время пользователь №2 нажмет ту же кнопку и его запрос пройдет быстрее и он получит 10, то №1 не должен получить тот же номер, когда его запрос выполнится.
А вообще рассуждать о сферических пользователях в вакууме нажимающих сферические кнопки можно долго.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы