47

In the movie theatre I go to they have ticket kiosks that allow you to select the seats you want; they also have a website that does the same (the website also has a countdown timer of like 30 secs in which you must choose a seat).

While I understand things such as database transactions and other techniques for handling multiple simultaneous users, I just can't get my head around how multiple people can be allowed to select a seat at the same time; is it as simple as the first one to press BUY gets the seats and the other person will get an error message, or am I missing something?

mbwasi
  • 581

5 Answers5

35

The classic method to do this is to use a transactional database (so there's no clashes) and to do a tentative allocation of the seat to you that expires after some length of time (e.g., 10 minutes for kiosks) that gives you enough time to pay. If the (customer-visible) transaction falls through or times out, the seat allocation can be released back into the pool. (All state changes are processed via the transactional database, and one customer-visible transaction might require many database-level transactions.)

Airlines will use a similar system (though much more complex due to the need to handle multiple flight legs!) for booking seats online. I would imagine that the timeout would be considerably longer; airline tickets are usually booked further ahead than movie tickets, and are more expensive as well.

8

The 30 seconds you have seen are nowadays often more like 15 mins. I don't believe there is a database transaction active for that duration.

If I was to design such a system, this is how I would do it: Have the business objects Booking and Reservation. Bookings are essentially confirmed (i.e. paid) reservations. I would store them in the same DB table and distinguish by an attribute or two.

When fetching available seats, you would query both bookings and reservations.

When someone selects a seat, you create a new reservation, thus showing other customers the seat as taken. A second reservation for the same seat will be declined - the DB update or insert will fail. If the customer confirms/pays for the reservation, you transition it to a booking. In a periodic batch job you delete all reservations older than 15 mins (or whatever time you give your customers).

Hugo G
  • 270
5

There are at least 2 business processes involved here.

  • Process one:

Show available seats.

  • Process two:

Book a selected seat.

Since these processes don't follow one another immoderately, and since 2 people may select the same seat the concurrency issue arises.

If your database design assigns the correct uniqueness constraint so that the combination of:

-TheaterID

-SeatID

-EventID

are unique, then the database will prevent duplicates.

The following scenario is also possible but will be taken care of by the above suggested implementation:

Assuming a grid view of available for a given theater and a given event can be displayed:

  1. User1 displays available seats (and gets seats 1 and 2)
  2. User2 displays available seats (and gets seats 1 and 2)
  3. User1 talks a bit with the customer on the phone
  4. User2 goes and books seat 2 for his customer
  5. User1 tries to book seat 2 for his customer (because it shows as available on his screen)
  6. The unique index prevents step 5 from commuting the data.

So all what you need to do may be nothing more correct database design and proper choice on constraints.

Other more complex approaches are possible if you want, using transaction queues. In this case, requests are written first to a queue then fires a process every n seconds but that is hardly necessary or practical in your case.

The really interesting part is what should the list grid for user 1 show?

NoChance
  • 12,532
1

It goes with the database ACID property - Isolation. The database uses locks on the data to avoid concurrent modification of the data.

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

1

You can avoid the race condition if you delay allocating specific seats.

  1. Collect seating preferences from customer (number of seats, price, area of theatre, adjacent seats mandatory, etc...)
  2. Save the requested seating preferences in a queue
  3. One-by-one seating requests are pulled from queue, seats allocated according to preference and the booking completed if seats found.
  4. If booking completed, notify customers and mail tickets; otherwise, notify customer that no tickets matched preferences.
Ed James
  • 1,331
  • 1
  • 10
  • 14