Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
8  
"is it as simple as the first one to press BUY gets the seats and the other person will get an error message". That. –  Yannis Rizos Nov 3 '11 at 9:38
2  
Yeah probably, on a bussy day with like a dozen machines seems like that would be a pain though. –  mbwasi Nov 3 '11 at 9:48
2  
Perhaps, but keep in mind that users will be spending the majority of their time on other screens (entering payment details, waiting for tickets to print, etc.), so they won't all be picking seats at the same time, and not everyone has the same seat preferences, so even those who are picking at the same time will likely pick different seats. I wouldn't expect there to be all that many collisions. –  Dave Sherohman Nov 3 '11 at 10:22
1  
@JimG. For every possible solution, if both customers press buy at the exact same time (to the millisecond) one will get served and the other will get some sort of error message. There are beautiful ways to minimize the chance of that happening (technical and conceptual, as explained in the answers) but in the extraordinary situation it does happen then one request will be served and the other will fail. As simple as that. –  Yannis Rizos Nov 3 '11 at 20:38
1  
@JimG. It's not a type of behavior. Concurrency works to a point, if both requests reach at the exact same microtime, one will fail. You can of course build a nice error message around that, as in Hand-E-Food's comment, but the fact remains: It's as simple as serving one request and failing the other. I'm not saying you shouldn't do everything to ensure that failing is as user friendly as it can be or that you shouldn't safeguard around it. –  Yannis Rizos Nov 3 '11 at 23:00

4 Answers 4

up vote 19 down vote accepted

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.

share|improve this answer
    
Mind you, my local movie theater doesn't actually allocate seats normally. Instead, they over-provisioned the seats so that people can just turn up with minimal fuss. It's a different technique, but not one relevant to your question! –  Donal Fellows Nov 3 '11 at 11:13
    
Similar to picking seats for sporting events. You get your N number of seats reserved for 3 minutes while you decide if you actually want them and complete the payment. –  AndyMcKenna Nov 3 '11 at 12:24
    
Note that there are two different processes with, for instance, buying airline seats: first, you buy a ticket without a seat allocated. Second, when you get your boarding pass (or if you check in online) then you get a seat. The number of tickets are actually oversold because they know that, on average, a certain number don't show up for the flight. Seat allocation, however, seems to work by randomly assigning you a seat (first-come-first-serve) when you check in, and then allowing you to change the seat by picking an available one, then doing the transfer in a single transaction. –  Scott Whitlock Nov 3 '11 at 12:56
    
@Scott: Depends. They're a lot more cautious with international flights where the consequences of being denied boarding will be much more dire. (I've never seen an international flight with standby ticket arrangements.) The process of committing a multi-hop multi-airline international flight must be horribly complicated, what with the fact that it's not just airlines but also governments that like to know exactly what's going on… –  Donal Fellows Nov 3 '11 at 14:48
    
And the classic "dire consequence" of being denied boarding is where it causes someone's 48-hour transit visa to expire because their flight only happens twice a week. I've seen it take ages to sort those sorts of problems out (alas; I was queueing behind them at the same rebooking desk). –  Donal Fellows Nov 3 '11 at 14:49

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

share|improve this answer

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?

share|improve this answer

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.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.