У меня есть веб-сайт, на котором пользователи могут покупать билеты, но количество билетов обычно ограничено, и они быстро расходуются. Я пытаюсь внедрить систему условного депонирования, чтобы пользователь мог щелкнуть, чтобы получить x билетов, после чего я помещу их в состояние условного депонирования. Это дает им несколько минут, чтобы ввести данные своей кредитной карты и завершить покупку.
У меня есть три соответствующие таблицы :события, билеты и условное депонирование. Строка в таблице событий описывает само событие, включая максимальное количество доступных билетов.
Таблица билетов содержит следующее:
идентификатор пользователя _:пользователь, купивший билеты
номер _из _билетов:сколько билетов они купили
событие _идентификатор:соответствующее событие
Таблица условного депонирования содержит следующее:
идентификатор пользователя _:пользователь в процессе покупки билетов
номер _из _билетов:сколько билетов они хотят
событие _идентификатор:соответствующее событие
В настоящее время я делаю три запроса MySQL,один для максимального количества билетов, один для количества проданных билетов и один для количества билетов, уже находящихся на условном депонировании. Затем я вычисляю:
$remaining_tickets = $max_tickets - $tickets_sold - $tickets_in_escrow;
if ($remaining_tickets >= $tickets_desired)
{
beginEscrow($user_id, $event_id, $tickets_desired);
}
else
{
echo "Error: not enough ticket remain.";
}
Моя проблема в том, что несколько пользователей могут одновременно выполнять этот код. Если бы один пользователь позвонилbeginEscrow
после того, как другой пользователь уже прочитал количество билетов, уже находящихся на условном депонировании, возможно, я перепродаю шоу.
Я использую механизм InnoDB для своих таблиц и читал, как заблокировать одну строку с помощью SELECT.... FOR UPDATE
, но я не обновляю ни одной строки. Функция beginEscrow
просто вставит новую строку в таблицу условного депонирования. Я вычисляю $tickets_in_escrow
, читая все строки с правильным идентификатором события и складывая количество билетов в каждой из них.
Может я все неправильно делаю?
Нужно ли блокировать всю таблицу?
Я не могу быть первым, кто напишет систему условного депонирования билетов. Я гуглил себя до смерти, пытаясь найти какой-нибудь учебник по такого рода вещам, но вычеркнул. Любые идеи будут полезны.
Спасибо!