Атомарные операции MySQL и блокировка таблиц

У меня есть веб-сайт, на котором пользователи могут покупать билеты, но количество билетов обычно ограничено, и они быстро расходуются. Я пытаюсь внедрить систему условного депонирования, чтобы пользователь мог щелкнуть, чтобы получить 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, читая все строки с правильным идентификатором события и складывая количество билетов в каждой из них.

Может я все неправильно делаю?

Нужно ли блокировать всю таблицу?

Я не могу быть первым, кто напишет систему условного депонирования билетов. Я гуглил себя до смерти, пытаясь найти какой-нибудь учебник по такого рода вещам, но вычеркнул. Любые идеи будут полезны.

Спасибо!

7
задан user1493634 30 June 2012 в 23:37
поделиться