I am creating a module wherein customers
(all customers, not individual) should only be able to book a schedule of the same date to a maximum of 5 times in 2 tables, namely acceptance_bookings
, and turnover_bookings
.
For example, 5 customers booked a schedule of the same date (07-17-2019), 3 of which are acceptance_booking
, and 2 turnover_booking
. If other customers have attempted to book on the same date, they should be rejected.
Currently my implementation would look like the following:
** START OF TRANSACTION **
** CODE FOR INSERTING ACCEPTANCE OR TURNOVER BOOKING **
$acceptance_bookings = AcceptanceBooking::selectRaw("DATE(date) as date")
->havingRaw("DATE(date) = '$dateString'")
->get()
->count();
$turnover_bookings = TurnoverBooking::selectRaw("DATE(date) as date")
->havingRaw("DATE(date) = '$dateString'")
->get()
->count();
$total_count = $acceptance_bookings + $turnover_bookings;
if($total_count > 5)
** ROLLBACK THE DB TRANSACTION
** END OF TRANSACTION
I am worried that in race conditions, there is a chance that both inserts will get past the validation check at the end of the code which checks if there are more than 5 entries to that date.
In my implementation (code above), I insert the booking before I check if it actually is already past limit, and roll back the transaction if it is past 5 entries. Placing the condition before the insert would probably yield the same result in a race condition.
What is the best way to handle this scenario to avoid race conditions? The strict requirements I want to maintain is that there should never be more than 5 entries of the same booking schedules across the 2 tables.
Note: I cannot change the tables, like trying to create a booking table and have a reference ID to determine if it is an acceptance or turnover booking as I am integrating an already working system.