An online movie ticket booking system like BookMyShow lets you search movies and book tickets on the go. It also allows you to choose your set of preferred seats. Lets see how this system is designed.
Requirements
Functional Requirements
- It shall list the cities where cinemas are located.
- It shall have the list of cinemas where movies are currently being played in a city.
- The system shall have all the shows of a movie. A movie might have multiple shows at a cinema.
- Users shall be able to search movies by their title, genre, language and cinema across a city.
- After a movie is selected by a user, he shall get a list of running shows.
- Users shall be able to select a show at a particular cinema and book tickets (multiple).
- The users shall get the seating arrangement and should be able to book seats (out of the available ones) of their preference.
- System should send notifications when a ticket is booked ( with seat numbers, show timings, hall details etc.) or cancelled via email or text.
- Users shall be able to pay with credit card, debit card, or UPI to book tickets.
- Users shall be able to add coupon before making payment.
Non Functional Requirements
- System should be able to handle concurrent requests such as when two users try to book same set of seats at the same time.
- As we will be handling financial transactions, so the database should be ACID compliant.
Classes in our system
Now, lets design the classes for our system and how they will interact with each other.
These will be the main actors of our system :
- Admin : Admin will be able to add/remove movies and their shows. Also admin can block accounts in case of any suspicious activity.
- User : User shall be able to search movies and shows and book tickets.
- Guest : Guests will be able to search movies but will have to create an account to book tickets.
- System : System will have the details of all the movies and shows. Will be responsible for sending notifications regarding booking or cancellation.
- Front Desk Officer : Will take care of booking or cancelling tickets.
The other main classes for our system would be :
- Cinema : The main part of organization where movies will be played. It will be having attributes like name, location, halls etc.
- Cinema Hall : Each cinema will be having multiple cinema halls.
- Movie Show : Each cinema hall might be running multiple shows a day for different movies. It will have attributes like movie details, cinema hall, start time and end time etc.
- Movie : Its the main entity of our system. It will have attributes like name, genre, release date, ratings, reviews, comments etc.
- Cinema Hall Seat : Each cinema hall will have many seats and seats can be of different types like Gold, Silver, Regular etc.
- Show Seat : Since each cinema hall can have multiple shows we will have this class which will store if seat is booked or not.
- Booking : A booking can be made by a user and a user can book multiple seats. It will have attributes like movie, show, show seats, payment details etc.
- Payment : This class will have attributes for payment related info.
- Notification : This is to send out notifications to users.
Database
We primarily have two types of data here :
Structured Relational Data : The data relating to the bookings, payments and seats must be ACID compliant and will be stored in relational database such as SQL.
Unstructured Data : The data related to movie's comments, reviews, ratings, description etc. can be stored in non-relational database such as MongoDB.
Use Cases
Make a Booking
- A user/guest or front desk officer enters the search criteria to like name, genre, city, language etc to search the movie.
- The system will perform the search and returns the results.
- If no results are returned, user can refine their search criteria.
- The user will select the movie and show and would be prompted to create an account if its a guest user. Once the account is created for guest user, he can book seats.
- Next the user would be redirected to the seat booking page
- User selects the seats and goes to the payment page.
- Once payment is done the booking is confirmed and user would be notified with the details.
Cancel a Booking
- To cancel a booking user will enter the booking number or can select the one from active bookings.
- System will validate if the booking was made by the same customer and is still active.
- If the validation is successful, system will cancel the booking and update the available seats for the show.
- System will issue the refund as per the policies and notify the user.
Handling the case when multiple users try to book the same seats at the same time
There might be a case that two or more users try to book same seats at the same time. We will have to handle concurrency to make our system reliable and to avoid ending up booking same seats for two users.
There can be multiple ways to solve the concurrency problem here:
DB Locking
Once a user starts booking a seat we can book that seat temporarily for that user for a fixed interval of time, say 5 or 10 mins. To maintain this we can have columns like start time and end time against each show seat. As soon as a user starts booking we can update the start time as current time and end time as current time + 10 mins. In addition to these, we can maintain a flag %[isReserved] (which stores if a seat is booked) and user Id. And to fetch the details of available seats for any further users we can update the query to fetch the fetch the seats where end time is greater than current time and seat is not reserved. Once a booking is completed we can update the isReserved flag to true.
Transaction Isolation Levels
We can use transaction isolation levels in our DB. We can set the transaction isolation level as Serializable which is the highest isolation level and locks the rows before we update them.
Thread Synchronization
In case we have a single instance running i.e. one JVM we can consider the booking function to be the critical section. This will allow only one thread to access the critical section at a time.
Synchronization in distributed cache
If we have a distributed system, the approach of declaring a critical section would not work as a synchronization block can provide access to shared resource on a single JVM and not across multiple JVMs. To handle this scenario in a distributed system we can use distributed cache like Redis or HazelCast that can read and update the value in one atomic operation.
These are some of the ways we can handle concurrency in our system. For more details you can refer How does BookMyShow handle concurrent bookings.
Thanks for your time. I hope this article helped in providing an insight of how a movie booking system is designed. Feel free to comment and follow for more such articles.