Heads-up: this article can contain traces of technical terms.
You want to be very sure that a ticket buyer cannot book a seat that has already been booked by another ticket buyer. Of course, it's the whole point of assigning a seat to a single person: you don't want it to be available anymore to the rest of the world.
A programmer's natural reaction to this is: before allowing a ticket buyer to book a seat, let's check whether this seat is actually free in the first place, and then only book it if it is.
While this double checking looks like a great idea at first sight, in fact it's not. Not only is it unnecessary, it's actually harmful: it will give you a false sense of security.
What is double checking?
(Note: don't do this! see below for the reasons why, and for the solution)
Suppose a user selects a seat A-1 for an event and continues through the ticket flow. Then when the seat needs to be booked, the programmer of your ticket system decided to do 2 things
- first, a status check: the system performs an API call to seats.io (typically one of the reporting API calls) to fetch the status of seat A-1.
- then, the status change: if A-1 is free, do another API call to actually book it.
The important point to note is that there are 2 API calls, that both go over the - very unreliable - internet. Anything can happen to either one of them, and anything can happen in between them.
Double checking is harmful
The status check and the status change are performed as two separate API calls. They both take some time to complete, and so there is some time in between them. Meaning that it's perfectly possible that the seat status has changed in between the calls!
An example of what could happen:
- the status check tells you that seat A-1 is free
- another user books A-1, invisible to your current thread
- you perform the status change API call to book the seat, still thinking it was free.
Why is this harmful? Because it can lead to duplicate bookings in your system.
You could be tempted into not checking the result of the status change API call. After all, you just checked the seat status in step 1.
However, that means that you'll register the booking in step 3 as successful, and so that A-1 will be booked twice in your ticketing system.
In summary: you can never be certain of the status of a seat. It could have been changed in between API calls.
Since you can't trust the response of the status check API call anyway, it's unnecessary and harmful to do double checking.
Instead of double checking before changing the seat status, you should just perform the status change call, and carefully handle both the success and failure case.
Whether or not a status change call was successful, is indicated by the http response seats.io sends you. We're using standard http status codes, such as 200 OK, 400 Bad Request, etc.
- If the http status code of the response was in the 2xx range, you can be absolutely sure and certain that the status change was successful. In case of a booking, this means the seat was free and bookable, and that it was booked.
- if the http status code is in another range (4xx or 5xx), you can be absolutely sure that the change status call was not successful. In that case you should check the response body to see what exactly the reason was.
Why does this work? Because the change status call is transactional, and because seats.io prevents double bookings not just in its code, but at database level.
In over 13.5 million bookings, there was not a single case of a double booking in the seats.io system. On the other hand, we do regularly see issues caused by the double checking strategy.
- Don't double-check a seat status before changing it.
- Instead, just change the status and correctly handle both the success and failure cases.