Creates a seat reservation with automatic expiration after 15 minutes. This endpoint uses a distributed Redis lock mechanism to prevent double-booking and ensure thread-safety across multiple service instances.
Important timing requirement: After creating a reservation, you must wait 2-3 seconds for the Kafka reservation-created event to be processed before adding the seat to the cart. Failing to wait will result in a “Reservation not found” error.
The reservation process uses a distributed lock with the following characteristics:
Lock key pattern: lock:seat:{seatId}
Lock TTL: 30 seconds
Lock implementation: Redis SET NX with token-based release
Concurrency control: Prevents race conditions during seat reservation
From CreateReservationCommandHandler.cs:19-21,41-48:
private const string RedisLockKeyPrefix = "lock:seat:";private const int LockExpirySeconds = 30;private const int ReservationTTLMinutes = 15;var lockKey = $"{RedisLockKeyPrefix}{request.SeatId:N}";var lockToken = await _redisLock.AcquireLockAsync(lockKey, TimeSpan.FromSeconds(LockExpirySeconds));if (lockToken is null){ throw new InvalidOperationException($"Could not acquire lock for seat {request.SeatId}. Seat may be reserved or locked.");}
Identifier for the customer making the reservation. Can be a user ID, email address, or any unique customer identifier.Examples: "customer-123", "[email protected]"
Returned when the seat cannot be reserved due to conflicts:
Seat already reserved: Another customer has already reserved this seat and the reservation hasn’t expired
Lock acquisition failed: The Redis distributed lock couldn’t be acquired within the timeout (5 seconds), indicating high contention or another process holding the lock
The 409 Conflict response for lock acquisition failure is rare but can occur during very high concurrent load. The client should retry after a brief delay.
The complete reservation-to-purchase flow requires these steps:
1
Get Event Seatmap
Call GET /events/{eventId}/seatmap (Catalog service) to retrieve available seats
2
Create Reservation
Call POST /reservations (this endpoint) to reserve the selected seat
3
Wait for Event Processing
Critical: Wait 2-3 seconds for the Kafka reservation-created event to be consumed by the Ordering service
4
Add to Cart
Call POST /cart/add (Ordering service) with the reservationId from step 2
5
Complete Purchase
Call POST /orders/checkout (Ordering service) to finalize the purchase
Expiration Notice: Reservations automatically expire after 15 minutes. If the customer doesn’t add the seat to their cart and complete checkout within this timeframe, the reservation will be released and the seat becomes available again.
The reservation is stored in PostgreSQL with the following structure:
CREATE TABLE Reservations ( Id UUID PRIMARY KEY, SeatId UUID NOT NULL, CustomerId VARCHAR NOT NULL, CreatedAt TIMESTAMP NOT NULL, ExpiresAt TIMESTAMP NOT NULL, Status VARCHAR NOT NULL);