Double-booking under load
Availability checks and booking creation run inside a single transaction with row-level locking on the vehicle, so concurrent checkouts serialise instead of racing. The loser gets a clean conflict response, not a corrupted booking.