A Spring Boot-based ticket booking system that handles concurrent ticket bookings with support for async processing, transaction management, and optimistic locking.
- Framework: Spring Boot 3.5.3
- Language: Java 21
- Database: H2 (In-memory)
- ORM: Spring Data JPA
- Security: Spring Security
- Build Tool: Maven
- Additional Features: Async Processing, Transaction Management
ticketBooking/
βββ src/main/java/com/bookingSystem/ticketBooking/
β βββ config/
β β βββ DataLoader.java # Initial data setup
β β βββ SecurityConfig.java # Security configuration
β β βββ ThreadPoolConfig.java # Async thread pool config
β βββ controller/
β β βββ BookingController.java # Booking REST endpoints
β β βββ EventController.java # Event REST endpoints
β β βββ UserController.java # User REST endpoints
β βββ entity/
β β βββ Booking.java # Booking entity with status enum
β β βββ Event.java # Event entity with versioning
β β βββ User.java # User entity
β βββ repository/
β β βββ BookingRepository.java # Booking data access
β β βββ EventRepository.java # Event data access with custom queries
β β βββ UserRepository.java # User data access
β βββ service/
β β βββ BookingService.java # Booking business logic
β β βββ EventService.java # Event business logic
β β βββ UserService.java # User business logic
β βββ TicketBookingApplication.java # Main application class
βββ src/main/resources/
β βββ application.properties # Application configuration
β βββ static/ # Static web resources
βββ src/test/java/
β βββ ConcurrentBookingTest.java # Concurrent booking tests
β βββ TicketBookingApplicationTests.java
βββ pom.xml # Maven configuration
classDiagram
class User {
-Long id
-String username
-String password
-String email
-String role
-List bookings
+getId() Long
+getUsername() String
+getPassword() String
+getEmail() String
+getRole() String
+getBookings() List
}
class Event {
-Long id
-String name
-String venue
-LocalDateTime eventDate
-Integer totalSeats
-Integer availableSeats
-Double price
-List bookings
-Long version
+getId() Long
+getName() String
+getVenue() String
+getEventDate() LocalDateTime
+getTotalSeats() Integer
+getAvailableSeats() Integer
+getPrice() Double
+getBookings() List
+getVersion() Long
}
class Booking {
-Long id
-User user
-Event event
-Integer seatsBooked
-LocalDateTime bookingDate
-Double totalAmount
-BookingStatus status
+getId() Long
+getUser() User
+getEvent() Event
+getSeatsBooked() Integer
+getBookingDate() LocalDateTime
+getTotalAmount() Double
+getStatus() BookingStatus
}
class BookingStatus {
<<enumeration>>
CONFIRMED
CANCELLED
PENDING
}
class UserService {
-UserRepository userRepository
-PasswordEncoder passwordEncoder
+getAllUsers() List
+getUserById(Long) Optional
+getUserByUsername(String) Optional
+createUser(User) User
+updateUser(User) User
+deleteUser(Long) void
+existsByUsername(String) boolean
+existsByEmail(String) boolean
}
class EventService {
-EventRepository eventRepository
+getAllEvents() List
+getAvailableEvents() List
+getEventById(Long) Optional
+searchEventsByName(String) List
+createEvent(Event) Event
+updateEvent(Event) Event
+deleteEvent(Long) void
+getEventByIdWithLock(Long) Optional
}
class BookingService {
-BookingRepository bookingRepository
-EventRepository eventRepository
-UserRepository userRepository
-ConcurrentHashMap eventLocks
+bookTicket(Long, Long, Integer) Booking
+bookTicketAsync(Long, Long, Integer) CompletableFuture
+getAllBookings() List
+getBookingById(Long) Optional
+getUserBookings(Long) List
+getEventBookings(Long) List
+cancelBooking(Long) boolean
+getBookingCountForEvent(Long) Long
}
class UserController {
-UserService userService
+getAllUsers() ResponseEntity
+getUserById(Long) ResponseEntity
+createUser(User) ResponseEntity
+updateUser(Long, User) ResponseEntity
+deleteUser(Long) ResponseEntity
}
class EventController {
-EventService eventService
+getAllEvents() ResponseEntity
+getAvailableEvents() ResponseEntity
+getEventById(Long) ResponseEntity
+searchEvents(String) ResponseEntity
+createEvent(Event) ResponseEntity
+updateEvent(Long, Event) ResponseEntity
+deleteEvent(Long) ResponseEntity
}
class BookingController {
-BookingService bookingService
+getAllBookings() ResponseEntity
+getBookingById(Long) ResponseEntity
+bookTicket(BookingRequest) ResponseEntity
+bookTicketAsync(BookingRequest) CompletableFuture
+getUserBookings(Long) ResponseEntity
+getEventBookings(Long) ResponseEntity
+cancelBooking(Long) ResponseEntity
+getBookingCountForEvent(Long) ResponseEntity
}
class UserRepository {
<<interface>>
+findByUsername(String) Optional
+existsByUsername(String) boolean
+existsByEmail(String) boolean
}
class EventRepository {
<<interface>>
+findAvailableEvents() List
+findByNameContaining(String) List
+findByIdWithLock(Long) Optional
}
class BookingRepository {
<<interface>>
+findByUserId(Long) List
+findByEventId(Long) List
+findByUserUsername(String) List
+countByEventId(Long) Long
}
%% Entity Relationships
User ||--o{ Booking : "has many"
Event ||--o{ Booking : "has many"
Booking ||--|| User : "belongs to"
Booking ||--|| Event : "belongs to"
Booking ||--|| BookingStatus : "has status"
%% Service Dependencies
UserService --> UserRepository : "uses"
EventService --> EventRepository : "uses"
BookingService --> BookingRepository : "uses"
BookingService --> EventRepository : "uses"
BookingService --> UserRepository : "uses"
%% Controller Dependencies
UserController --> UserService : "uses"
EventController --> EventService : "uses"
BookingController --> BookingService : "uses"
%% Repository Relationships
UserRepository -.-> User : "manages"
EventRepository -.-> Event : "manages"
BookingRepository -.-> Booking : "manages"
- User Management: Registration, authentication, and user roles
- Event Management: Create, update, and manage events with seat availability
- Booking System: Reserve tickets with real-time seat availability updates
- Optimistic Locking: Version-based locking on Event entities
- Pessimistic Locking: ReentrantLock for critical booking sections
- Async Processing: Non-blocking ticket booking with CompletableFuture
- Spring Security: Authentication and authorization
- Transaction Management: ACID compliance for booking operations
- Password Encryption: BCrypt password encoding
- Input Validation: Entity-level and service-level validation
- Booking Status Management: CONFIRMED, CANCELLED, PENDING states
- Seat Availability Tracking: Real-time seat count updates
- Concurrent Booking Support: Handle multiple simultaneous bookings
- Booking History: Track user booking history and event bookings
- Users Table: User authentication and profile information
- Events Table: Event details with seat management and versioning
- Bookings Table: Booking records linking users to events
- User (1) ββ (N) Booking: One user can have multiple bookings
- Event (1) ββ (N) Booking: One event can have multiple bookings
- Booking (N) ββ (1) User: Each booking belongs to one user
- Booking (N) ββ (1) Event: Each booking is for one event
GET /api/users - Get all users
GET /api/users/{id} - Get user by ID
POST /api/users - Create new user
PUT /api/users/{id} - Update user
DELETE /api/users/{id} - Delete user
GET /api/events - Get all events
GET /api/events/available - Get available events
GET /api/events/{id} - Get event by ID
GET /api/events/search - Search events by name
POST /api/events - Create new event
PUT /api/events/{id} - Update event
DELETE /api/events/{id} - Delete event
GET /api/bookings - Get all bookings
GET /api/bookings/{id} - Get booking by ID
POST /api/bookings/book - Create booking (synchronous)
POST /api/bookings/book-async - Create booking (asynchronous)
GET /api/bookings/user/{userId} - Get user bookings
GET /api/bookings/event/{eventId} - Get event bookings
DELETE /api/bookings/{bookingId} - Cancel booking
GET /api/bookings/count/event/{eventId} - Get booking count for event
- Java 21 or higher
- Maven 3.6+
-
Clone the repository
git clone <repository-url> cd ticketBooking
-
Build the project
./mvnw clean install
-
Run the application
./mvnw spring-boot:run
-
Access the application
- API Base URL:
http://localhost:8080 - H2 Console:
http://localhost:8080/h2-console
- API Base URL:
- Database: H2 in-memory database (configured in
application.properties) - Security: Basic authentication enabled
- Async Processing: Custom thread pool configuration
- JPA: Hibernate as JPA provider with DDL auto-generation
./mvnw testThe system includes specialized tests for concurrent booking scenarios to ensure thread safety and data integrity.
- Layered Architecture: Clear separation of concerns with Controller-Service-Repository pattern
- Dependency Injection: Spring's IoC container manages component lifecycle
- Async Processing: CompletableFuture for non-blocking operations
- Transaction Management: Declarative transactions with Spring's @Transactional
- Concurrent Access Control: Combination of optimistic and pessimistic locking strategies
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.