Backend Event Ticketing System dengan Java Native + MySQL yang mencegah overselling
Dibuat oleh: Davin Gabriel J
Submission: Backend Web Developer - The Gatekeeper Logic
Platform backend untuk sistem tiket event online yang memfasilitasi:
- Organizer untuk membuat dan mengelola event
- Customer untuk memesan tiket event
- Sistem untuk mencegah overselling dengan transaction locking
Overselling Prevention: Sistem menggunakan Pessimistic Locking untuk memastikan tidak ada tiket yang terjual melebihi kapasitas, bahkan ketika terjadi concurrent requests dari multiple users.
- CRUD Users - Manajemen data pengguna (Customer & Organizer)
- CRUD Events - Buat, update, dan kelola event
- CRUD Bookings - Sistem pemesanan tiket
- Pessimistic Locking - Mencegah race condition
- Transaction Management - ACID compliance
- Partial Update - Update field tertentu saja
- Status Management - Tracking status booking & event
- Database transaction dengan BEGIN/COMMIT/ROLLBACK
- SELECT FOR UPDATE untuk row-level locking
- Input validation di Service layer
- Error handling yang comprehensive
src/
βββ Main.java # Entry point & HTTP Server
βββ controllers/
β βββ UserController.java # User endpoints
β βββ EventController.java # Event endpoints
β βββ BookingController.java # Booking endpoints
βββ services/
β βββ UserService.java # Business logic - Users
β βββ EventService.java # Business logic - Events
β βββ BookingService.java # Business logic - Bookings
βββ dao/
β βββ UserDAO.java # Database access - Users
β βββ EventDAO.java # Database access - Events
β βββ BookingDAO.java # Database access - Bookings
βββ models/
βββ User.java # User entity
βββ Event.java # Event entity
βββ Booking.java # Booking entity
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
full_name VARCHAR(100) NOT NULL,
phone VARCHAR(20),
role ENUM('CUSTOMER', 'ORGANIZER') DEFAULT 'CUSTOMER',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE events (
id INT AUTO_INCREMENT PRIMARY KEY,
organizer_id INT NOT NULL,
event_name VARCHAR(200) NOT NULL,
description TEXT,
event_date DATETIME NOT NULL,
location VARCHAR(200) NOT NULL,
total_capacity INT NOT NULL,
available_tickets INT NOT NULL,
ticket_price DECIMAL(10,2) NOT NULL,
status ENUM('ACTIVE', 'CANCELLED', 'COMPLETED') DEFAULT 'ACTIVE',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (organizer_id) REFERENCES users(id)
);CREATE TABLE bookings (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
event_id INT NOT NULL,
quantity INT NOT NULL,
total_price DECIMAL(10,2) NOT NULL,
status ENUM('PENDING', 'CONFIRMED', 'CANCELLED') DEFAULT 'PENDING',
booking_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (event_id) REFERENCES events(id)
);- Java JDK 11+
- MySQL 8.0+
- Git
git clone https://github.com/Davin164/BE_Submission_The-Gatekeeper-Logic.git
cd BE_Submission_The-Gatekeeper-Logic# Login ke MySQL
mysql -u root
mysql -u root -p (jika ada password)
# Jalankan database.sql
source database.sql# Copy .env.example ke .env
cp .env.example .env
# Edit .env sesuai konfigurasi MySQL kamu
nano .envIsi .env:
DB_HOST=localhost
DB_PORT=3306
DB_NAME=event_ticketing
DB_USER=root
DB_PASSWORD=your_password# Compile
bash compile.sh
# Run server
bash run.shServer akan berjalan di: http://localhost:8080
http://localhost:8080/api
GET /api/usersResponse Success (200):
[
{
"id": 1,
"username": "johndoe",
"email": "john@example.com",
"fullName": "John Doe",
"phone": "081234567890",
"role": "CUSTOMER",
"createdAt": "2024-12-24T10:30:00"
}
]GET /api/users/{id}POST /api/users
Content-Type: application/jsonRequest Body:
{
"username": "johndoe",
"email": "john@example.com",
"password": "password123",
"fullName": "John Doe",
"phone": "081234567890",
"role": "CUSTOMER"
}Response Success (201):
{
"id": 1,
"username": "johndoe",
"email": "john@example.com",
"fullName": "John Doe",
"role": "CUSTOMER"
}PUT /api/users/{id}
Content-Type: application/jsonRequest Body (Partial):
{
"fullName": "John Doe Updated",
"phone": "081234567999"
}DELETE /api/users/{id}GET /api/eventsResponse Success (200):
[
{
"id": 1,
"organizerId": 1,
"eventName": "Music Festival 2025",
"description": "Amazing music festival",
"eventDate": "2025-06-15T18:00:00",
"location": "Jakarta Convention Center",
"totalCapacity": 5000,
"availableTickets": 4500,
"ticketPrice": 150000.00,
"status": "ACTIVE",
"createdAt": "2024-12-24T10:00:00"
}
]GET /api/events/{id}POST /api/events
Content-Type: application/jsonRequest Body:
{
"organizerId": 1,
"eventName": "Music Festival 2025",
"description": "Amazing music festival",
"eventDate": "2025-06-15 18:00:00",
"location": "Jakarta Convention Center",
"totalCapacity": 5000,
"ticketPrice": 150000.00
}Response Success (201):
{
"id": 1,
"eventName": "Music Festival 2025",
"availableTickets": 5000,
"status": "ACTIVE"
}PUT /api/events/{id}
Content-Type: application/jsonRequest Body (Partial):
{
"ticketPrice": 120000.00,
"status": "ACTIVE"
}DELETE /api/events/{id}GET /api/bookingsGET /api/bookings/{id}GET /api/bookings/user/{userId}GET /api/bookings/event/{eventId}POST /api/bookings
Content-Type: application/jsonRequest Body:
{
"userId": 2,
"eventId": 1,
"quantity": 2
}Response Success (201):
{
"id": 1,
"userId": 2,
"eventId": 1,
"quantity": 2,
"totalPrice": 300000.00,
"status": "PENDING",
"bookingDate": "2024-12-24T14:30:00"
}Response Error (400):
{
"error": "Not enough tickets available"
}PUT /api/bookings/{id}/confirmPUT /api/bookings/{id}/cancelDELETE /api/bookings/{id}- Install extension Thunder Client
- Import collection atau create new request
- Set method dan URL
- Untuk POST/PUT, tambahkan body JSON
- Klik Send
Gunakan script yang sudah disediakan:
# Test semua endpoints
bash test_api.sh# Terminal 1: Booking 100 tiket
curl -X POST http://localhost:8080/api/bookings \
-H "Content-Type: application/json" \
-d '{"userId": 2, "eventId": 1, "quantity": 100}'
# Terminal 2: Booking 100 tiket (simultaneous)
curl -X POST http://localhost:8080/api/bookings \
-H "Content-Type: application/json" \
-d '{"userId": 3, "eventId": 1, "quantity": 100}'- Language: Java (Native) JDK16
- Database: MySQL 8.0+
- Run API Test: Thunder Client (extension VSCode)
Davin Gabriel J
- GitHub: @Davin164
- Submission ini untuk kepentingan Tugas Backend Web Developer GDGoC 2026
- Studi Kasus: "The Gatekeeper Logic"
- Platform Tiket Event Online dengan Overselling Prevention
- Bisa diintegrasikan dengan Spring boot (Framework Java)
Made with β and π» in Indonesia Last Updated: 24 December 2025