0

I am working on a ticketing system using Laravel. Are there any known techniques to prevent double bookings in a ticketing system.

Scenario
Ticket A has only 6 tickets available, User A comes in and adds 4 into their basket. I intend to make an API call to the database to deduct 4 from the available ticket number and then start a 10 minute timer within which User A must complete payment or else the tickets will be added back to the database.

However, a big flaw in my method is this: if the user simply closes the window, I have no way of checking the elapsed time to re-add the tickets back. Any ideas or other known techniques that I can make use of?

I already took a look at this question but still run into the same issue/flaw

oluwatyson
  • 251
  • 4
  • 18
  • 3
    Don't rely on the Client's browser to keep track of the time. Record when you reserved the quantity, then have your back-end system check (every minute) for any `locked_at` values greater than 10 minutes and unlock them. That being said, this question is more conceptual, and thus a little broad for Stackoverflow. You're unlikely to get any concrete answers, just suggestions. – Tim Lewis Jul 05 '21 at 19:46

1 Answers1

2

Locking while accessing the Model would solve most of your worries and don't let core business logic being enforced on the front end.

Use database transactions to secure only one row is modified at a time and check that the ticket amount is available or else fail. This can produce database locks, that should be handled for better user experiences. There will not be written anything to the database, before the transaction is executed without any errors.

Thorwing the exception will cancel the operation and secure the operation to be atomic.

$ticketsToBeBought = 4;

DB::transaction(function ($query) {
    $ticket = Ticket::where('id', 'ticket_a')->firstOrFail();

    $availableTickets = $ticket->tickets_available;
    $afterBuy = $availableTickets - $ticketsToBeBought;

    if ($afterBuy < 0) {
        throw new NoMoreTicketsException();
    }

    $ticket->tickets_available = $afterBuy;
    $ticket->save();

    // create ticket models or similar for the sale
});

This is a fairly simple approach to a very complex problem, that big companies normally tackle. But i hope it can get you going in the right direction and this is my approach to never oversell tickets.

mrhn
  • 17,961
  • 4
  • 27
  • 46
  • Thanks for this answer. I have now taken a look at Database transactions and I full understand the concept now bar one element. How does it achieve the locking feature? From my understanding its mechanism that ensures ALL or nothing is implemented when modifying a record? How does that translate to locking? – oluwatyson Jul 06 '21 at 06:46
  • When a transaction is open and you access and write to a row, sql ensures nothing else can be written and therefor the tickets can not be taken by anyone else. Hope that makes sense :) – mrhn Jul 06 '21 at 08:27