I have a website where users can buy tickets, but the number of tickets is usually limited and fast. I am trying to implement a escrow system so that the user can click that they need x number of tickets, after which I will put them in a conditional escrow state. This gives them a few minutes to enter their credit card details and complete the purchase.
I have three relevant tables: events, tickets, and escrow. A row in the event table describes the event itself, including the maximum number of tickets available.
The ticket table contains the following:
user_id : user who purchased the tickets
number_of_tickets : how many tickets they purchased
event_id : corresponding event
The escrow table contains the following:
user_id : user in the ticketing process
number_of_tickets : how many tickets do they want
event_id : corresponding event
I am currently making three MySQL queries, one for the maximum tickets, one for the number of tickets sold, and one for the number of tickets already in deposit. Then I calculate:
$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."; }
My problem is that multiple instances of the same code can be executed by multiple users at the same time. If one user had to call beginEscrow after another user has already read the number of tickets already in escrow, it is possible that I tried the show.
I use the InnoDB engine for my tables, and I read how to lock a single row using SELECT .... FOR UPDATE , but I am not updating a single row. The beginEscrow function simply inserts a new row into the escrow table. I compute $tickets_in_escrow by reading all the lines with the correct event ID and adding the number of tickets in each of them.
Maybe I'll fix it?
Do I need to lock the entire table?
I cannot be the first to write a escrow system. I searched myself to death, trying to find some kind of textbook on this subject, but crossed out. Any ideas would be helpful.
Thanks!