Case Study: Design a Hotel Reservation System
“Hotel reservation system giong nhu mot san bay quoc te — hang trieu nguoi cung muon dat cho tren cung mot chuyen bay, nhung moi chuyen chi co gioi han cho ngoi. Neu ban qua so ghe, hanh khach se bi ‘bumped’ va uy tin cua hang bay mat vinh vien.”
Tags: system-design hotel-reservation concurrency-control overbooking inventory-management alex-xu-vol2 case-study Student: Hieu Prerequisite: Tuan-02-Back-of-the-envelope · Tuan-07-Database-Sharding-Replication · Tuan-08-Message-Queue Lien quan: Tuan-11-Microservices-Pattern · Tuan-14-AuthN-AuthZ-Security · Tuan-15-Data-Security-Encryption · Case-Design-Payment-System Reference: Alex Xu, System Design Interview Volume 2 — Chapter 6: Hotel Reservation System
1. Context & Why — Tai sao Hotel Reservation System quan trong?
1.1 Analogy: He thong dat phong khach san nhu Booking.com / Agoda
Hieu, em tuong tuong minh dang xay dung he thong cho Booking.com hoac Agoda. Moi ngay co hang trieu nguoi tren toan the gioi truy cap de tim phong khach san. Ho search theo thanh pho, ngay check-in/check-out, so nguoi, roi chon phong va dat.
Van de la: khach san “Muong Thanh Grand Da Nang” chi co 50 phong Deluxe. Khi co 200 nguoi cung muon dat phong Deluxe cho dem 31/12 (Giao thua), he thong phai:
- Hien thi chinh xac so phong con trong — khong duoc hien thi “con phong” khi da het
- Dam bao khong ban qua (overbooking) — 50 phong thi chi cho 50 nguoi dat (hoac nhieu hon 1 chut neu co overbooking strategy)
- Xu ly dong thoi — 200 nguoi click “Dat ngay” cung luc, chi 50 nguoi thanh cong
- Khong charge 2 lan — nguoi dung click retry vi mang cham, khong duoc tao 2 booking
- Tich hop thanh toan — sau khi dat phong, phai thu tien hoac giu the (authorization hold)
1.2 Tai sao day la bai toan kho?
| Thach thuc | Giai thich |
|---|---|
| Concurrency control | Hang ngan nguoi cung dat phong mot thoi diem — lam sao dam bao khong ban qua so phong? |
| Inventory accuracy | So phong phai chinh xac real-time. Hien thi “con 2 phong” nhung thuc te da het = trai nghiem te |
| Double booking prevention | Nguoi dung click dat 2 lan, mang cham retry — khong duoc tao 2 reservation |
| Peak traffic | Dip le Tet, Noel, Black Friday — traffic tang 10-50x so voi ngay thuong |
| Cross-service consistency | Dat phong thanh cong nhung payment fail → phai rollback inventory |
| Search performance | Tim khach san theo location, gia, rating, amenities — dataset lon, query phuc tap |
| Overbooking as business decision | Airlines overbooking 5-10% la binh thuong. Khach san cung vay. Phai configurable |
1.3 Tai sao Backend Dev can hieu Hotel Reservation?
| Ly do | Giai thich |
|---|---|
| Concurrency la core skill | Hieu concurrency control (pessimistic/optimistic locking) giup em xu ly bat ky bai toan nao co shared resource |
| Inventory management pattern | E-commerce (ton kho), ticketing (ghe ngoi), airline (cho) — tat ca deu dung pattern tuong tu |
| Real-world distributed transaction | Dat phong + thanh toan + cap nhat inventory = distributed transaction dien hinh |
| Read-heavy + Write-critical | Search (read) nhieu gap boi, nhung reservation (write) phai chinh xac 100% |
| Interview favorite | Day la bai thuong gap trong system design interview vi no bao phu nhieu concept |
Aha Moment: Hotel reservation khong chi la “CRUD rooms va bookings”. Core problem la concurrency control tren shared inventory — va cach giai quyet no anh huong den toan bo architecture.
Step 1 — Requirements
1.1 Functional Requirements
| Requirement | Mo ta | Priority |
|---|---|---|
| Search hotels | Tim khach san theo location, check-in/check-out date, so khach, filters (gia, rating, amenities) | P0 |
| View hotel details | Xem thong tin chi tiet khach san: hinh anh, mo ta, room types, gia, reviews | P0 |
| View room availability | Xem so phong con trong cho tung loai phong, tung ngay | P0 |
| Reserve a room | Dat phong: chon room type, ngay, nhap thong tin khach, thanh toan | P0 |
| Cancel reservation | Huy dat phong, refund theo chinh sach | P0 |
| Admin: manage inventory | Hotel admin cap nhat so phong, gia, dong/mo phong theo mua | P0 |
| Admin: view reservations | Hotel admin xem danh sach booking, check-in/check-out status | P1 |
| Price management | Dynamic pricing theo mua, ngay le, demand | P1 |
| Loyalty program | Tich diem, uu dai cho khach hang than thiet | P2 |
1.2 Non-Functional Requirements
| Requirement | Target | Ly do |
|---|---|---|
| Availability | 99.99% (4 nines) | Downtime = mat doanh thu truc tiep |
| Consistency | Strong consistency cho reservation | Khong duoc ban qua so phong |
| Latency (search) | P99 < 500ms | User experience — search phai nhanh |
| Latency (reservation) | P99 < 2s (bao gom payment) | Chap nhan cham hon search vi co payment |
| Durability | Zero data loss cho reservation | Mat booking = mat tien + mat khach |
| Scalability | Handle peak 10x normal traffic | Dip le, flash sale |
1.3 Scale Estimation (Pham vi bai toan)
| Thong so | Gia tri | Ghi chu |
|---|---|---|
| So khach san | 5,000 | Quy mo Agoda Vietnam |
| Tong so phong | 1,000,000 (1M) | Trung binh 200 phong/khach san |
| So loai phong trung binh | 20 / khach san | Standard, Deluxe, Suite, Family, etc. |
| Read:Write ratio | 3:7 cho reservation page | Nhieu nguoi xem nhung it nguoi dat |
| Occupancy rate trung binh | 70% | Industry average |
| Peak season multiplier | 10x | Tet, Noel, summer holidays |
| Average reservation duration | 2-3 dem | Business + leisure mix |
Chu y: Ty le read:write 3:7 cho reservation page la KHAC voi search page. Search page la read-heavy (90%+ read). Reservation page co nhieu write vi moi lan dat phong = write inventory + write reservation + write payment.
Step 2 — High-Level Design
2.1 System Components Overview
| Component | Vai tro | Analogy |
|---|---|---|
| Hotel Service | Quan ly thong tin khach san, phong, hinh anh, amenities | Catalog cua khach san |
| Search Service | Tim kiem khach san theo nhieu tieu chi, ranking | Google cho khach san |
| Rate Service | Quan ly gia phong theo ngay, mua, demand (dynamic pricing) | Bo phan dinh gia |
| Inventory Service | Quan ly so phong kha dung theo ngay — THE critical service | Kho hang |
| Reservation Service | Xu ly dat phong, huy phong, thay doi booking | Quay le tan |
| Payment Service | Tich hop PSP, xu ly thanh toan, refund | Thu ngan |
| Notification Service | Gui email/SMS xac nhan booking, reminder check-in | Nhan vien CSKH |
2.2 High-Level Architecture
flowchart TB subgraph "Client Layer" WEB[Web App<br/>React / Next.js] MOBILE[Mobile App<br/>iOS / Android] ADMIN[Hotel Admin<br/>Dashboard] end subgraph "API Gateway" GW[API Gateway<br/>Rate Limiting · Auth · Routing] end subgraph "Core Services" HOTEL[Hotel Service<br/>Hotel & Room Info] SEARCH[Search Service<br/>Elasticsearch] RATE[Rate Service<br/>Dynamic Pricing] INV[Inventory Service<br/>Room Availability] RESV[Reservation Service<br/>Booking Management] PAY[Payment Service<br/>PSP Integration] end subgraph "Supporting Services" NOTIFY[Notification Service<br/>Email · SMS · Push] LOYALTY[Loyalty Service<br/>Points · Rewards] end subgraph "Data Stores" PGDB[(PostgreSQL<br/>Reservation · Inventory)] REDIS[(Redis<br/>Cache · Session)] ES[(Elasticsearch<br/>Hotel Search Index)] MQ[Message Queue<br/>Kafka] end subgraph "External" PSP[PSP<br/>Stripe · VNPay] CDN[CDN<br/>Hotel Images] end WEB --> GW MOBILE --> GW ADMIN --> GW GW --> HOTEL GW --> SEARCH GW --> RESV HOTEL --> PGDB HOTEL --> CDN SEARCH --> ES RATE --> PGDB RATE --> REDIS INV --> PGDB INV --> REDIS RESV --> PGDB RESV --> INV RESV --> PAY RESV --> MQ PAY --> PSP MQ --> NOTIFY MQ --> LOYALTY style INV fill:#e53935,color:#fff style RESV fill:#1e88e5,color:#fff style PGDB fill:#43a047,color:#fff
Highlight: Inventory Service (mau do) la critical path — moi reservation deu phai di qua no. Neu Inventory Service cham hoac sai, toan bo he thong bi anh huong.
2.3 API Design Overview
| API | Method | Mo ta |
|---|---|---|
/hotels/search | GET | Tim khach san theo location, date, filters |
/hotels/{id} | GET | Xem chi tiet khach san |
/hotels/{id}/rooms | GET | Xem danh sach room types va gia |
/hotels/{id}/rooms/availability | GET | Check so phong con trong theo ngay |
/reservations | POST | Tao reservation moi |
/reservations/{id} | GET | Xem chi tiet reservation |
/reservations/{id}/cancel | POST | Huy reservation |
/admin/hotels/{id}/inventory | PUT | Cap nhat so phong (admin) |
/admin/hotels/{id}/rates | PUT | Cap nhat gia phong (admin) |
2.4 Basic Reservation Flow (High-Level)
1. User search khach san tai "Da Nang" cho ngay 31/12 - 02/01
2. Search Service tra ve danh sach khach san co phong trong
3. User chon "Muong Thanh Grand" → xem room types va gia
4. User chon "Deluxe Room" — hien thi "con 3 phong" — click "Dat ngay"
5. Reservation Service: kiem tra inventory → con phong → tao reservation (PENDING)
6. User nhap thong tin + thanh toan
7. Payment Service: charge card hoac authorization hold
8. Payment thanh cong → Reservation chuyen CONFIRMED → Inventory giam 1
9. Notification Service: gui email xac nhan cho user
Step 3 — Deep Dive
3.1 Data Model — Mo hinh du lieu
Hotel Table
| Field | Type | Mo ta |
|---|---|---|
hotel_id | UUID | Primary key |
name | VARCHAR(255) | Ten khach san |
address | TEXT | Dia chi |
city | VARCHAR(100) | Thanh pho |
country | VARCHAR(100) | Quoc gia |
latitude | DECIMAL(10,8) | Vi do |
longitude | DECIMAL(11,8) | Kinh do |
star_rating | SMALLINT | So sao (1-5) |
description | TEXT | Mo ta chi tiet |
amenities | JSONB | Tien ich (pool, gym, spa, wifi…) |
images | JSONB | Danh sach URL hinh anh |
status | ENUM | ACTIVE, INACTIVE, SUSPENDED |
created_at | TIMESTAMP | Thoi diem tao |
updated_at | TIMESTAMP | Thoi diem cap nhat |
Room Type Table
| Field | Type | Mo ta |
|---|---|---|
room_type_id | UUID | Primary key |
hotel_id | UUID | Foreign key → Hotel |
name | VARCHAR(100) | Ten loai phong (Standard, Deluxe, Suite) |
description | TEXT | Mo ta phong |
max_occupancy | SMALLINT | So nguoi toi da |
base_price | BIGINT | Gia co ban (don vi nho nhat — VND dong) |
amenities | JSONB | Tien ich phong (minibar, balcony, bathtub) |
images | JSONB | Hinh anh loai phong |
status | ENUM | ACTIVE, INACTIVE |
Room Type Inventory Table — THE CORE TABLE
| Field | Type | Mo ta |
|---|---|---|
inventory_id | UUID | Primary key |
hotel_id | UUID | Foreign key → Hotel |
room_type_id | UUID | Foreign key → Room Type |
date | DATE | Ngay cu the |
total_inventory | INT | Tong so phong loai nay |
total_reserved | INT | So phong da dat |
total_available | INT | So phong con trong (= total - reserved) |
version | INT | Optimistic locking version |
Tai sao co bang inventory rieng theo ngay? Vi so phong kha dung khac nhau moi ngay. Ngay 31/12 co the het phong nhung ngay 02/01 con nhieu. Hotel admin cung co the dong mot so phong de bao tri vao ngay cu the. Schema nay cho phep quan ly inventory per-day granularity.
Unique constraint tren inventory table:
UNIQUE (hotel_id, room_type_id, date)
Moi hotel + room type + date chi co dung mot record inventory.
CHECK constraint chong overbooking:
CHECK (total_reserved <= total_inventory)
-- Hoac voi overbooking allowance:
CHECK (total_reserved <= FLOOR(total_inventory * (1 + overbooking_percentage / 100.0)))
Reservation Table
| Field | Type | Mo ta |
|---|---|---|
reservation_id | UUID | Primary key, dong thoi la idempotency key |
hotel_id | UUID | Foreign key → Hotel |
room_type_id | UUID | Foreign key → Room Type |
guest_id | UUID | Foreign key → User |
check_in_date | DATE | Ngay check-in |
check_out_date | DATE | Ngay check-out |
num_rooms | SMALLINT | So phong dat |
total_price | BIGINT | Tong gia (VND) |
currency | VARCHAR(3) | ISO 4217 |
status | ENUM | PENDING, CONFIRMED, CANCELLED, CHECKED_IN, CHECKED_OUT, NO_SHOW |
payment_id | UUID | Foreign key → Payment |
special_requests | TEXT | Yeu cau dac biet |
created_at | TIMESTAMP | Thoi diem tao |
updated_at | TIMESTAMP | Thoi diem cap nhat |
cancelled_at | TIMESTAMP | Thoi diem huy (nullable) |
cancellation_reason | TEXT | Ly do huy (nullable) |
Reservation State Machine
stateDiagram-v2 [*] --> PENDING: User click "Dat phong" PENDING --> CONFIRMED: Payment thanh cong PENDING --> CANCELLED: Payment fail / timeout / user cancel CONFIRMED --> CHECKED_IN: Khach den nhan phong CONFIRMED --> CANCELLED: Huy truoc ngay check-in (theo policy) CONFIRMED --> NO_SHOW: Khach khong den CHECKED_IN --> CHECKED_OUT: Khach tra phong CANCELLED --> [*] NO_SHOW --> [*] CHECKED_OUT --> [*]
Allowed state transitions:
- PENDING → CONFIRMED: VALID (payment success)
- PENDING → CANCELLED: VALID (payment fail, timeout, user cancel)
- CONFIRMED → CHECKED_IN: VALID (guest arrives)
- CONFIRMED → CANCELLED: VALID (guest cancels before check-in date, subject to cancellation policy)
- PENDING → CHECKED_IN: INVALID (khong the check-in khi chua thanh toan)
- CHECKED_OUT → CONFIRMED: INVALID (khong the quay lai trang thai truoc)
3.2 Reservation Flow — Luong dat phong chi tiet
Two-Phase Reservation: Tentative Hold → Confirmed
Reservation khong phai la mot buoc duy nhat. No la 2 phases:
| Phase | Mo ta | Thoi gian | Inventory impact |
|---|---|---|---|
| Phase 1: Tentative Hold | User click “Dat phong” → he thong tam giu phong (PENDING) | 10-15 phut | Inventory giam (hold) |
| Phase 2: Confirm | Payment thanh cong → reservation chuyen CONFIRMED | Sau payment | Inventory confirmed |
Tai sao can 2 phases? Vi giua luc user click “Dat phong” va luc payment hoan tat co the mat 5-10 phut (nhap thong tin the, OTP, 3D Secure). Trong thoi gian do, phai “giu” phong de nguoi khac khong dat mat. Nhung neu user khong thanh toan trong 10-15 phut → release hold → tra phong lai inventory.
Reservation Sequence Diagram
sequenceDiagram participant U as User participant FE as Frontend participant RS as Reservation Service participant IS as Inventory Service participant PS as Payment Service participant DB as PostgreSQL participant NS as Notification Service U->>FE: Click "Dat phong Deluxe"<br/>Check-in: 31/12, Check-out: 02/01 FE->>RS: POST /reservations<br/>{hotel_id, room_type_id, dates, guest_info} Note over RS: Generate reservation_id<br/>(cung la idempotency key) RS->>IS: Check availability<br/>{hotel_id, room_type_id, dates} IS->>DB: SELECT total_available<br/>FROM room_type_inventory<br/>WHERE date IN (31/12, 01/01) alt Con phong (available >= 1) IS-->>RS: Available = YES RS->>IS: Reserve (tentative hold) IS->>DB: UPDATE room_type_inventory<br/>SET total_reserved += 1<br/>WHERE date IN (31/12, 01/01)<br/>AND total_available > 0 Note over IS: Inventory giam 1 cho moi dem IS-->>RS: Hold confirmed RS->>DB: INSERT reservation<br/>(status = PENDING) RS-->>FE: Reservation PENDING<br/>Redirect to payment Note over FE: Timer: 10 phut de thanh toan U->>FE: Nhap thong tin thanh toan FE->>PS: Process payment<br/>{reservation_id, amount} PS-->>FE: Payment SUCCESS FE->>RS: Confirm reservation<br/>{reservation_id, payment_id} RS->>DB: UPDATE reservation<br/>SET status = CONFIRMED RS-->>FE: Booking CONFIRMED! RS->>NS: Send confirmation email NS-->>U: Email: "Dat phong thanh cong" else Het phong (available = 0) IS-->>RS: Available = NO RS-->>FE: Sorry, het phong! end
Hold Expiration — Xu ly khi user khong thanh toan
sequenceDiagram participant CRON as Scheduler<br/>(chay moi phut) participant RS as Reservation Service participant IS as Inventory Service participant DB as PostgreSQL CRON->>RS: Check expired holds RS->>DB: SELECT reservations<br/>WHERE status = PENDING<br/>AND created_at < NOW() - 10 min Note over RS: Tim thay 5 reservations<br/>da qua 10 phut chua thanh toan loop Moi reservation het han RS->>DB: UPDATE reservation<br/>SET status = CANCELLED RS->>IS: Release hold IS->>DB: UPDATE room_type_inventory<br/>SET total_reserved -= 1<br/>WHERE date IN (reservation dates) Note over IS: Tra phong lai inventory end
Aha Moment: Hold expiration la critical. Neu khong co mechanism nay, user co the “giu” phong mai ma khong bao gio thanh toan → het phong ao (phong trong nhung khong ai dat duoc). Phai co background job chay moi phut de release expired holds.
3.3 Concurrency Control — THE Core Problem
Day la bai toan kho nhat cua hotel reservation system. Khi 200 nguoi cung click “Dat phong” cho cung 1 room type vao cung 1 ngay, va chi con 3 phong, lam sao dam bao chi co 3 nguoi dat thanh cong?
Van de: Race Condition
Thread A: Read available = 3 → Reserve 1 → Write available = 2
Thread B: Read available = 3 → Reserve 1 → Write available = 2 (SAI! Phai la 1)
Thread C: Read available = 3 → Reserve 1 → Write available = 2 (SAI! Phai la 0)
Ket qua: 3 nguoi dat nhung inventory chi giam 1 → Overbooking!
Co 3 approaches chinh de giai quyet:
Approach 1: Pessimistic Locking (SELECT FOR UPDATE)
Co che: Lock row truoc khi doc. Cac transaction khac phai cho cho den khi lock duoc release.
Flow:
Transaction A:
BEGIN;
SELECT total_reserved, total_available
FROM room_type_inventory
WHERE hotel_id = 'H001' AND room_type_id = 'RT001' AND date = '2026-12-31'
FOR UPDATE; -- Lock row!
-- total_reserved = 47, total_available = 3
UPDATE room_type_inventory
SET total_reserved = 48, total_available = 2
WHERE inventory_id = '...';
COMMIT; -- Release lock
Transaction B: (cho cho den khi A commit)
BEGIN;
SELECT ... FOR UPDATE; -- Now available = 2
UPDATE ... SET total_reserved = 49, total_available = 1;
COMMIT;
Transaction C: (cho cho den khi B commit)
BEGIN;
SELECT ... FOR UPDATE; -- Now available = 1
UPDATE ... SET total_reserved = 50, total_available = 0;
COMMIT;
Transaction D: (cho cho den khi C commit)
BEGIN;
SELECT ... FOR UPDATE; -- Now available = 0
-- Khong du phong → ROLLBACK, bao user "het phong"
ROLLBACK;
| Uu diem | Nhuoc diem |
|---|---|
| Don gian, de hieu | Giam throughput — cac transaction phai xep hang cho |
| Chac chan khong overbooking | Co the deadlock neu lock nhieu rows sai thu tu |
| Phu hop khi contention cao | Latency tang khi nhieu nguoi cung dat |
Approach 2: Optimistic Locking (Version Column)
Co che: Khong lock khi doc. Khi write, kiem tra version co thay doi khong. Neu thay doi → conflict → retry.
Flow:
Transaction A:
-- Step 1: Read (KHONG lock)
SELECT total_reserved, total_available, version
FROM room_type_inventory
WHERE hotel_id = 'H001' AND room_type_id = 'RT001' AND date = '2026-12-31';
-- total_reserved = 47, total_available = 3, version = 10
-- Step 2: Update voi version check
UPDATE room_type_inventory
SET total_reserved = 48, total_available = 2, version = 11
WHERE inventory_id = '...' AND version = 10;
-- affected_rows = 1 → SUCCESS
Transaction B: (doc cung luc voi A)
-- Step 1: Read
SELECT ... -- total_reserved = 47, total_available = 3, version = 10
-- Step 2: Update voi version check
UPDATE ... SET total_reserved = 48, version = 11
WHERE ... AND version = 10;
-- affected_rows = 0 → CONFLICT! (A da update version len 11)
-- Step 3: RETRY tu Step 1
SELECT ... -- total_reserved = 48, total_available = 2, version = 11
UPDATE ... SET total_reserved = 49, version = 12
WHERE ... AND version = 11;
-- affected_rows = 1 → SUCCESS
| Uu diem | Nhuoc diem |
|---|---|
| Khong blocking — read khong bi lock | Nhieu retry khi contention cao (hot room, peak season) |
| Throughput cao hon pessimistic | Retry storm: 200 nguoi cung retry → chi 1 nguoi thanh cong moi lan |
| Phu hop khi conflict it | Latency khong du doan (phu thuoc so lan retry) |
Approach 3: Database Constraints (CHECK Constraint)
Co che: Dung database constraint de enforce rule. Let DB handle concurrency.
Flow:
-- Tao constraint khi tao table:
ALTER TABLE room_type_inventory
ADD CONSTRAINT chk_no_overbooking
CHECK (total_reserved <= total_inventory);
-- Moi reservation chi can:
UPDATE room_type_inventory
SET total_reserved = total_reserved + 1
WHERE hotel_id = 'H001'
AND room_type_id = 'RT001'
AND date = '2026-12-31';
-- Neu total_reserved + 1 > total_inventory
-- → CHECK constraint violation → DB tu reject
-- → Application nhan error → bao user "het phong"
| Uu diem | Nhuoc diem |
|---|---|
| Don gian nhat — chi can 1 UPDATE statement | Dua hoan toan vao DB — kho customize logic |
| DB tu xu ly concurrency (row-level lock cua UPDATE la atomic) | Error handling: phai catch constraint violation error |
| Khong can version column, khong can explicit lock | Kho implement overbooking percentage (can phuc tap hon) |
| Reliable — DB engine da duoc test ky luong | Performance phu thuoc vao DB engine |
So sanh 3 approaches
| Tieu chi | Pessimistic Locking | Optimistic Locking | DB Constraints |
|---|---|---|---|
| Do phuc tap | Trung binh | Cao (retry logic) | Thap |
| Throughput | Thap (blocking) | Cao (no blocking) | Cao |
| Consistency | Strong | Eventual (retry) | Strong |
| Contention cao | OK nhung cham | Nhieu retry → cham | OK |
| Deadlock risk | Co (multi-row lock) | Khong | Khong |
| Overbooking prevention | Chac chan | Chac chan (sau retry) | Chac chan |
| Khi nao dung | Inventory update quan trong, moderate traffic | Read-heavy, low contention | Khi muon don gian, trust DB |
| Hotel reservation | Phu hop cho peak season | Phu hop cho ngay thuong | Recommended — don gian va hieu qua |
Recommendation tu Alex Xu: Dung Database Constraints (Approach 3) lam primary strategy. Ly do: don gian nhat, DB engine da toi uu cho concurrent updates, va CHECK constraint dam bao khong bao gio overbooking (tru khi co tinh). Ket hop voi Optimistic Locking (version column) cho cac truong hop can retry logic.
3.4 Overbooking Strategy — Chien luoc ban qua
Overbooking la gi?
Overbooking la viec co tinh ban nhieu phong hon so phong thuc te. Nghe nhu bug nhung thuc ra la business decision.
| Industry | Overbooking rate | Ly do |
|---|---|---|
| Airlines | 5-15% | ~5% hanh khach no-show. Ban 105 ve cho 100 ghe → toi uu doanh thu |
| Hotels | 5-10% | ~10% khach cancel muon hoac no-show |
| Car rental | 10-20% | Cao hon vi khach thuong thay doi ke hoach |
Tai sao hotel can overbooking?
| Tinh huong | Khong overbooking | Co overbooking |
|---|---|---|
| 100 phong, 10% no-show | Ban 100 phong, 10 khach no-show → 90% occupancy | Ban 110 phong, 10 no-show → 100% occupancy |
| Doanh thu | Mat 10% doanh thu | Toi da doanh thu |
| Rui ro | Khong co rui ro | Neu it no-show hon du kien → phai “relocate” khach |
Implementation: Configurable Overbooking Threshold
Them cot overbooking_percentage vao room_type_inventory:
| Field | Type | Mo ta |
|---|---|---|
overbooking_percentage | DECIMAL(5,2) | % overbooking cho phep. Default = 0 (khong overbooking) |
Logic kiem tra availability:
Vi du: Hotel co 100 phong Deluxe, overbooking 10%:
CHECK constraint voi overbooking:
CHECK (total_reserved <= FLOOR(total_inventory * (1 + overbooking_percentage / 100.0)))
Aha Moment: Overbooking KHONG phai la bug — no la business decision duoc cau hinh boi hotel manager. Moi khach san co overbooking rate khac nhau. Luxury hotel (Ritz-Carlton) thuong overbooking 0-2% vi cost cua relocation rat cao. Budget hotel co the overbooking 10-15%.
Xu ly khi overbooking xay ra (khach den nhung het phong)
| Buoc | Hanh dong |
|---|---|
| 1 | He thong phat hien: so khach check-in > so phong thuc te |
| 2 | Tim khach san doi tac (partner hotel) co phong trong |
| 3 | Upgrade khach len phong tot hon (neu con) |
| 4 | Relocate khach sang partner hotel + chiu chi phi |
| 5 | Compensation: refund + voucher cho lan sau |
| 6 | Ghi nhan metric: overbooking_relocation_count |
3.5 Idempotency — Chong dat phong trung lap
Van de: Client Retry → Double Booking
User click "Dat phong" → Network cham → Khong nhan response
→ User click "Dat phong" lan 2
→ Server nhan 2 request → Tao 2 reservation → Charge 2 lan!
Day la van de kinh dien trong moi transaction system. Giai phap: Idempotency Key.
Implementation: reservation_id la Idempotency Key
| Buoc | Mo ta |
|---|---|
| 1 | Frontend generate reservation_id (UUID v4) truoc khi gui request |
| 2 | Gui request: POST /reservations voi reservation_id trong body |
| 3 | Server check: SELECT * FROM reservations WHERE reservation_id = ? |
| 4a | Neu khong ton tai → tao reservation moi |
| 4b | Neu da ton tai → tra ve reservation cu (KHONG tao moi) |
Database enforcement:
UNIQUE INDEX ON reservations(reservation_id)
Neu 2 request cung reservation_id den cung luc:
- Request 1: INSERT thanh cong
- Request 2: UNIQUE constraint violation → catch error → return existing reservation
Tai sao frontend generate ID? Vi neu server generate ID, khi response bi mat (network timeout), client khong biet ID → khong the retry an toan. Khi frontend generate ID, client luon gui cung ID khi retry → server nhan ra request trung → tra ve ket qua cu.
Idempotency cho Payment
Tuong tu, payment cung can idempotency:
| Field | Vai tro |
|---|---|
reservation_id | Idempotency key cho reservation |
payment_idempotency_key | Idempotency key gui cho PSP (Stripe Idempotency-Key header) |
POST /payments
Headers: Idempotency-Key: {reservation_id}
Body: {amount: 2000000, currency: "VND"}
→ PSP (Stripe) se khong charge 2 lan voi cung Idempotency-Key
Aha Moment: Idempotency key ngan double charge — mot trong nhung loi nghiem trong nhat trong booking system. Khach hang bi charge 2 lan = mat uy tin + refund process phuc tap + review xau.
3.6 Handling High Concurrency During Flash Sales
Van de: 1000 nguoi cung dat 10 phong
Trong flash sales (gia soc, Black Friday), co the co hang ngan request dong thoi cho 1 hotel voi so phong rat han che. Luc nay:
- Optimistic locking: retry storm — 1000 nguoi retry, chi 1 thanh cong moi vong → 999 retry → latency bung
- Pessimistic locking: 1000 transaction xep hang cho → timeout → user experience te
- DB constraint: 1000 UPDATE dong thoi → DB row-level lock → van bottleneck
Giai phap: Queue-Based Reservation
Thay vi de 1000 request truc tiep vao DB, dung message queue de serialize requests:
flowchart LR subgraph "Incoming Requests" R1[Request 1] R2[Request 2] R3[Request 3] R4[Request ...] R5[Request 1000] end subgraph "Queue" MQ[Message Queue<br/>Kafka / Redis Stream<br/>FIFO] end subgraph "Consumer" C1[Reservation Worker<br/>Process sequentially] end subgraph "Database" DB[(PostgreSQL<br/>Inventory)] end subgraph "Result" S[SUCCESS<br/>Phong da dat] F[FAILED<br/>Het phong] end R1 --> MQ R2 --> MQ R3 --> MQ R4 --> MQ R5 --> MQ MQ --> C1 C1 --> DB C1 --> S C1 --> F
Flow:
| Buoc | Mo ta |
|---|---|
| 1 | 1000 requests den → tat ca duoc dua vao message queue |
| 2 | API tra ve ngay: “Yeu cau cua ban dang duoc xu ly” (202 Accepted) |
| 3 | Consumer doc tu queue, xu ly tuan tu (1 request mot luc) |
| 4 | Consumer check inventory → con phong → reserve → tra ket qua qua WebSocket/polling |
| 5 | Het phong → cac request con lai bi reject |
| 6 | Notification gui cho user: “Dat phong thanh cong” hoac “Het phong” |
Trade-off: Chuyen tu synchronous (click → ket qua ngay) sang asynchronous (click → cho → ket qua sau). User experience thay doi: hien thi “Dang xu ly…” thay vi ket qua lien. Nhung dam bao khong overbooking va khong crash khi traffic spike.
Redis cho Fast Inventory Check
Truoc khi dua request vao queue, dung Redis de pre-check inventory:
| Buoc | Mo ta |
|---|---|
| 1 | Khi inventory thay doi → update Redis: SET inv:H001:RT001:2026-12-31 3 (con 3 phong) |
| 2 | Request den → check Redis: GET inv:H001:RT001:2026-12-31 |
| 3 | Neu Redis = 0 → tra ve “Het phong” ngay, KHONG can vao queue |
| 4 | Neu Redis > 0 → dua vao queue de xu ly |
| 5 | Sau khi reserve thanh cong → DECR inv:H001:RT001:2026-12-31 |
Luu y quan trong: Redis chi la pre-check (approximate), KHONG phai source of truth. Source of truth luon la PostgreSQL. Redis co the sai (stale data) → nhung DB constraint se bat loi cuoi cung.
Multi-layer protection: Redis reject 90% request nhanh (het phong) → Queue handle 10% con lai tuan tu → DB constraint bao ve cuoi cung. Ba layer nay ket hop dam bao zero overbooking voi high throughput.
3.7 Caching Strategy
Hotel & Room Data — Cache-Friendly
| Du lieu | Cache strategy | TTL | Ly do |
|---|---|---|---|
| Hotel info (ten, dia chi, amenities) | Cache-aside voi Redis | 1 gio | Thay doi it, read nhieu |
| Room type info (mo ta, hinh anh) | Cache-aside voi Redis | 1 gio | Tuong tu hotel info |
| Hotel images | CDN cache | 24 gio | Static content, rat it thay doi |
| Hotel reviews/ratings | Cache-aside | 15 phut | Thay doi vua phai |
| Search results | Cache-aside voi Elasticsearch | 5 phut | Thay doi theo inventory |
Inventory Data — NGUY HIEM khi cache
| Van de | Giai thich |
|---|---|
| Stale inventory | Cache noi “con 2 phong” nhung thuc te da het → user dat phong → fail → bad UX |
| Cache invalidation | Moi khi co reservation/cancellation → phai invalidate cache ngay |
| Race condition | Invalidate cache → 100 requests doc tu DB cung luc → cache stampede |
| Flash sale | Inventory thay doi lien tuc → cache luon bi invalidate → cache hit rate ~ 0% |
Ket luan: KHONG nen cache inventory data cho real-time availability check. Ly do:
- Inventory thay doi qua thuong xuyen (moi reservation → thay doi)
- Sai lech inventory = overbooking hoac lost revenue
- Cache invalidation phuc tap va error-prone
Aha Moment: “Not everything should be cached”. Inventory la write-heavy, accuracy-critical data. Cache no se tao nhieu van de hon giai quyet. Doc truc tiep tu DB (voi proper indexing) la an toan hon.
Ngoai le: Redis cho flash sale (section 3.6) la approximate pre-check, khong phai cache cho accurate availability. No chi de reject request nhanh khi chac chan het phong.
| Du lieu | Cache? | Ly do |
|---|---|---|
| Hotel info | Co | Read-heavy, rarely changes |
| Room type | Co | Read-heavy, rarely changes |
| Inventory (real-time) | KHONG | Write-heavy, accuracy-critical |
| Price/Rate | Co (short TTL) | Thay doi hang ngay nhung khong lien tuc |
| Search results | Co (short TTL) | Chap nhan slightly stale |
3.8 Database Choice
| Service | Database | Ly do |
|---|---|---|
| Reservation + Inventory | PostgreSQL | ACID required, transaction support, CHECK constraints, strong consistency |
| Hotel Search | Elasticsearch | Full-text search, geo-spatial queries, faceted search (filter theo gia, rating, amenities) |
| Caching | Redis | In-memory, sub-millisecond latency, data structures (String, Hash, Sorted Set) |
| Session | Redis | Fast session lookup, auto-expiry (TTL) |
| Hotel Images | S3 + CDN | Object storage cho hinh anh, CDN cho fast delivery |
| Analytics | ClickHouse / BigQuery | Phan tich booking trends, revenue, occupancy rates |
| Message Queue | Kafka | High throughput, durability, replay capability |
Tai sao PostgreSQL cho reservation? Vi reservation can ACID transactions — Atomicity (dat phong + giam inventory phai cung thanh cong hoac cung fail), Consistency (CHECK constraint), Isolation (concurrent updates), Durability (khong mat data). NoSQL (MongoDB, DynamoDB) khong co native ACID transaction phu hop cho bai toan nay.
3.9 Microservices Decomposition
flowchart TB subgraph "Public-Facing" SEARCH[Search Service<br/>Elasticsearch queries<br/>Stateless · Horizontally scalable] HOTEL[Hotel Service<br/>Hotel & Room CRUD<br/>Read-heavy · Cacheable] end subgraph "Core Transaction" RESV[Reservation Service<br/>Booking lifecycle<br/>Stateful · ACID required] INV[Inventory Service<br/>Room availability<br/>Hot path · Concurrency control] PAY[Payment Service<br/>PSP integration<br/>Idempotent · Retryable] end subgraph "Supporting" RATE[Rate Service<br/>Dynamic pricing<br/>Read-heavy · Cacheable] NOTIFY[Notification Service<br/>Email · SMS · Push<br/>Async · Fire-and-forget] LOYALTY[Loyalty Service<br/>Points · Rewards<br/>Eventually consistent] end SEARCH --> HOTEL SEARCH --> INV RESV --> INV RESV --> PAY RESV --> RATE RESV --> NOTIFY RESV --> LOYALTY style INV fill:#e53935,color:#fff style RESV fill:#1e88e5,color:#fff style PAY fill:#ff6f00,color:#fff
Scaling strategy cho tung service — tham chiếu Tuan-11-Microservices-Pattern:
| Service | Scaling strategy | Ly do |
|---|---|---|
| Search Service | Horizontal scale (nhieu instance) | Stateless, read-heavy |
| Hotel Service | Horizontal scale + cache | Stateless, read-heavy, cacheable |
| Rate Service | Horizontal scale + cache | Read-heavy, rate data cached |
| Inventory Service | Vertical scale (strong DB) + read replicas | Stateful, write-heavy, can strong consistency |
| Reservation Service | Horizontal scale (stateless logic) + shared DB | Business logic stateless, DB la bottleneck |
| Payment Service | Horizontal scale, idempotent | Stateless, PSP xu ly state |
| Notification Service | Horizontal scale + queue | Async, tolerant of delay |
Key insight: Inventory Service la bottleneck cua he thong. Scale no = scale DB (vertical + replication). Cac service khac co the horizontal scale de dang vi stateless.
3.10 Data Consistency — Saga Pattern cho Cross-Service Transaction
Van de: Distributed Transaction
Khi user dat phong, can thuc hien 3 buoc o 3 service khac nhau:
- Inventory Service: Giam so phong
- Payment Service: Charge user
- Reservation Service: Confirm booking
Neu buoc 2 (Payment) fail sau khi buoc 1 (Inventory) da thanh cong → inconsistency: phong da bi giam nhung khong co booking.
Saga Pattern — Choreography-Based
sequenceDiagram participant RS as Reservation Service participant IS as Inventory Service participant PS as Payment Service participant NS as Notification Service participant MQ as Kafka RS->>IS: 1. Reserve inventory (hold) IS-->>RS: Inventory held RS->>PS: 2. Process payment alt Payment SUCCESS PS-->>RS: Payment confirmed RS->>RS: 3. Update reservation → CONFIRMED RS->>MQ: Publish: BookingConfirmed MQ->>NS: 4. Send confirmation NS-->>RS: Email sent else Payment FAILED PS-->>RS: Payment failed RS->>IS: COMPENSATE: Release inventory IS-->>RS: Inventory released RS->>RS: Update reservation → CANCELLED RS->>MQ: Publish: BookingCancelled MQ->>NS: Send cancellation notice end
Saga Steps va Compensating Actions
| Step | Service | Forward Action | Compensating Action (khi fail) |
|---|---|---|---|
| 1 | Inventory Service | Reserve rooms (hold) | Release hold → tra phong lai |
| 2 | Payment Service | Charge card / Auth hold | Refund / void authorization |
| 3 | Reservation Service | Confirm reservation | Cancel reservation |
| 4 | Notification Service | Send confirmation email | Send cancellation email |
Failure scenarios:
| Scenario | Xay ra gi | Compensating actions |
|---|---|---|
| Step 1 fail (het phong) | Bao user “het phong” | Khong can compensate (chua lam gi) |
| Step 2 fail (payment declined) | Payment fail | Compensate Step 1: release inventory hold |
| Step 3 fail (DB error) | Reservation khong luu duoc | Compensate Step 2: refund payment. Compensate Step 1: release inventory |
| Step 4 fail (email fail) | Email khong gui duoc | Khong can compensate (non-critical) — retry email later |
Quan trong: Thu tu compensating actions la nguoc lai voi thu tu forward actions. Compensate tu buoc gan nhat nguoc ve buoc dau tien. Tham khao chi tiet tai Tuan-11-Microservices-Pattern.
Capacity Estimation — Uoc luong nang luc
Assumptions
| Thong so | Gia tri | Giai thich |
|---|---|---|
| So khach san | 5,000 | Quy mo medium platform |
| Tong so phong | 1,000,000 (1M) | 200 phong/khach san trung binh |
| Room types / khach san | 20 | Standard, Deluxe, Suite, etc. |
| Reservation/ngay | 100,000 (100K) | ~10% occupancy change per day |
| Search queries/ngay | 5,000,000 (5M) | 50x reservation volume |
| Average booking duration | 2.5 dem | Business + leisure mix |
| Peak-to-average ratio | 10x | Tet, Noel, summer |
| Average reservation payload | 1 KB | JSON with guest info |
| Average search payload | 2 KB | Response with hotel list |
Reservation QPS
Nhan xet: 11.6 TPS peak — day la moderate scale. PostgreSQL co the xu ly hang ngan TPS. Reservation khong phai bottleneck ve throughput. Concurrency control tren cung 1 row moi la van de chinh.
Search QPS
Nhan xet: 579 QPS peak cho search. Elasticsearch co the xu ly hang ngan QPS. Nhung moi query co the fan-out ra nhieu index → can toi uu query va cache.
Inventory Table Size
So records trong room_type_inventory:
Kich thuoc moi record:
Nhan xet: 3.65 GB — vua du cho single PostgreSQL instance. Nhung can partitioning theo date de toi uu query (chi query cac ngay trong tuong lai, khong can scan ngay da qua). Partition theo month la hop ly.
Reservation Storage
Nhan xet: 182.5 GB cho 5 nam — PostgreSQL xu ly thoai mai. Co the archive reservations cu hon 2 nam sang cold storage.
Cache Sizing
Nhan xet: 325 MB — Redis default max memory la 0 (unlimited), nhung 325 MB la rat nho. Mot Redis instance 1 GB la du.
Tom tat Estimation
| Metric | Value |
|---|---|
| Reservation QPS (peak) | ~12/s |
| Search QPS (peak) | ~580/s |
| Inventory table size | ~3.65 GB |
| Reservation storage/year | ~36.5 GB |
| 5-year reservation storage | ~182.5 GB |
| Redis cache | ~325 MB |
| Inventory records | ~36.5M |
Security — Bao mat
Payment Data Protection (PCI-DSS)
Tham khao chi tiet tai Case-Design-Payment-System va Tuan-15-Data-Security-Encryption.
| Nguyen tac | Ap dung cho Hotel Reservation |
|---|---|
| KHONG luu card number | Dung PSP (Stripe, VNPay) hosted payment page. Chi luu token |
| Tokenization | Card data → token. Em chi luu token + last 4 digits |
| TLS 1.2+ | Moi API call phai qua HTTPS. Khong bao gio truyen card data qua HTTP |
| PCI-DSS scope reduction | Dung hosted payment page → giam PCI-DSS compliance scope |
Prevent Price Manipulation
| Tan cong | Mo ta | Phong chong |
|---|---|---|
| Price tampering | User sua gia tren frontend (inspect element, intercept request) | Server-side price validation: luon tinh gia tu DB, KHONG tin gia tu client |
| Race condition exploit | Dat phong voi gia cu sau khi gia da tang | Lock gia tai thoi diem tao reservation, gia duoc tinh tren server |
| Coupon abuse | Dung coupon nhieu lan hoac coupon cua nguoi khac | Unique coupon per user, server-side validation, rate limiting |
Price validation flow:
| Buoc | Mo ta |
|---|---|
| 1 | Client gui: {hotel_id, room_type_id, dates} — KHONG gui price |
| 2 | Server tinh gia tu Rate Service: base_price x nights x tax |
| 3 | Server tra ve gia chinh thuc cho client hien thi |
| 4 | Client confirm → Server tinh gia LAI lan nua truoc khi charge |
| 5 | Neu gia thay doi giua luc hien thi va luc confirm → thong bao user gia moi |
Rule: KHONG BAO GIO tin gia tu client. Luon tinh gia tren server tai moi buoc.
Rate Limiting — Chong Inventory Scraping
| Tan cong | Mo ta | Phong chong |
|---|---|---|
| Inventory scraping | Bot crawl tat ca availability de ban lai (OTA arbitrage) | Rate limiting: 100 requests/phut/IP |
| Search abuse | Bot search lien tuc de theo doi gia | CAPTCHA sau 50 searches, rate limit per user |
| Reservation bot | Bot tu dong dat phong khi thay gia thap | Device fingerprinting, behavioral analysis |
| DDoS | Tan cong lam sap he thong | WAF (Web Application Firewall), CDN protection (Cloudflare) |
Rate limiting strategy — tham khao Tuan-09-Rate-Limiter:
| Endpoint | Rate limit | Ly do |
|---|---|---|
/hotels/search | 100 req/min/IP | Chong scraping |
/hotels/{id}/rooms/availability | 60 req/min/IP | Chong inventory scraping |
/reservations (POST) | 10 req/min/user | Chong booking bot |
/reservations/{id}/cancel | 5 req/min/user | Chong abuse |
User Data Privacy (GDPR / PDPA)
| Du lieu | Phan loai | Bao ve |
|---|---|---|
| Ten, email, SDT | PII (Personally Identifiable Information) | Encrypt at rest (AES-256), access control |
| Passport/CCCD | Sensitive PII | Encrypt + restricted access, auto-delete sau 30 ngay |
| Payment token | Payment data | PCI-DSS compliant storage |
| Booking history | Personal data | Accessible only by user + authorized staff |
| IP address, device info | Technical data | Log rotation, anonymize after 90 ngay |
| GDPR Right | Implementation |
|---|---|
| Right to access | API cho user xem toan bo data cua ho |
| Right to deletion | Soft delete + anonymize PII sau retention period |
| Right to portability | Export booking history dang JSON/CSV |
| Consent management | Explicit opt-in cho marketing emails |
DevOps & Monitoring — Van hanh va giam sat
Key Metrics to Monitor
| Metric | Mo ta | Alert Threshold | Severity |
|---|---|---|---|
| Reservation Success Rate | % dat phong thanh cong (khong tinh het phong) | < 95% → alert | P1 (Critical) |
| Overbooking Rate | % khach bi relocate do overbooking | > 2% → alert | P1 |
| Inventory Accuracy | Inventory trong DB vs thuc te (sau reconciliation) | Discrepancy > 0.1% → alert | P1 |
| Search Latency P99 | Thoi gian search 99th percentile | > 500ms → alert | P2 |
| Reservation Latency P99 | Thoi gian dat phong E2E | > 3s → alert | P2 |
| Payment Failure Rate | % thanh toan that bai | > 10% → alert | P1 |
| Hold Expiration Rate | % reservation PENDING bi timeout | > 30% → investigate | P3 |
| Cache Hit Rate | % request duoc serve tu cache | < 80% → investigate | P3 |
| DB Connection Pool | So connection hien tai / max | > 80% → alert | P2 |
| Queue Depth | So message trong Kafka waiting | > 10,000 → alert | P2 |
Dashboard Layout
| Panel | Metrics | Visualization |
|---|---|---|
| Booking Health | Success rate, volume, error breakdown | Time series (last 24h) |
| Inventory | Occupancy rate per city, overbooking events | Heatmap + counter |
| Search Performance | QPS, latency P50/P95/P99 | Line chart + histogram |
| Payment | Success/failure rate, PSP latency | Pie chart + time series |
| Infrastructure | CPU, memory, DB connections, cache hit rate | Gauge + sparkline |
| Business | Revenue, ADR (Average Daily Rate), RevPAR | Counter + trend |
Alerting Rules
| Alert | Condition | Action |
|---|---|---|
| Overbooking detected | Khach check-in > so phong available | Page on-call, tim phong thay the |
| Payment gateway down | PSP error rate > 50% cho 5 phut | Failover sang PSP backup, page team |
| Inventory discrepancy | DB inventory khac actual > threshold | Freeze booking cho hotel do, investigate |
| Search degradation | P99 > 2s cho 10 phut | Scale Elasticsearch nodes, check query performance |
| Expired hold spike | Hold expiration rate > 50% trong 1 gio | Check payment flow, PSP latency |
SLA Monitoring
| SLA | Target | Measurement |
|---|---|---|
| Uptime | 99.99% (52.6 phut downtime/nam) | Synthetic monitoring moi 30 giay |
| Search availability | 99.95% | Health check endpoint |
| Booking availability | 99.99% | End-to-end booking test moi 5 phut |
| Data durability | 99.999999999% (11 nines) | DB replication + backup verification |
Mermaid Diagrams — Tong hop
Diagram 1: High-Level Architecture (da co o Section 2.2)
Diagram 2: Reservation Flow (da co o Section 3.2)
Diagram 3: Concurrency Control Comparison
flowchart TB subgraph "Approach 1: Pessimistic Locking" P1[Transaction A<br/>SELECT ... FOR UPDATE] P2[Row LOCKED] P3[Transaction B<br/>WAITING...] P4[A commits → B proceeds] P1 --> P2 P2 --> P3 P3 -.->|wait| P4 end subgraph "Approach 2: Optimistic Locking" O1[Transaction A<br/>Read version=10] O2[Transaction B<br/>Read version=10] O3[A: UPDATE WHERE version=10<br/>SUCCESS → version=11] O4[B: UPDATE WHERE version=10<br/>CONFLICT → RETRY] O1 --> O3 O2 --> O4 end subgraph "Approach 3: DB Constraint" D1[Transaction A<br/>UPDATE reserved += 1] D2[Transaction B<br/>UPDATE reserved += 1] D3[DB: CHECK reserved <= total<br/>A: OK · B: OK or REJECT] D1 --> D3 D2 --> D3 end style P2 fill:#e53935,color:#fff style O4 fill:#ff6f00,color:#fff style D3 fill:#43a047,color:#fff
Diagram 4: Saga Pattern cho Reservation
flowchart TB START([User click Dat Phong]) --> S1 subgraph "Forward Flow" S1[Step 1: Reserve Inventory<br/>Inventory Service] S2[Step 2: Process Payment<br/>Payment Service] S3[Step 3: Confirm Booking<br/>Reservation Service] S4[Step 4: Send Notification<br/>Notification Service] end subgraph "Compensating Flow" C1[Compensate: Release Inventory<br/>Inventory Service] C2[Compensate: Refund Payment<br/>Payment Service] C3[Compensate: Cancel Booking<br/>Reservation Service] end S1 -->|Success| S2 S2 -->|Success| S3 S3 -->|Success| S4 S4 --> DONE([Booking Confirmed!]) S1 -->|Fail| FAIL1([Het phong]) S2 -->|Fail| C1 S3 -->|Fail| C2 C2 --> C1 C1 --> FAIL2([Booking Failed<br/>User notified]) style S1 fill:#1e88e5,color:#fff style S2 fill:#ff6f00,color:#fff style S3 fill:#43a047,color:#fff style S4 fill:#7b1fa2,color:#fff style C1 fill:#e53935,color:#fff style C2 fill:#e53935,color:#fff style C3 fill:#e53935,color:#fff
Diagram 5: Data Flow Overview
flowchart LR subgraph "Read Path" U1[User] -->|Search| GW1[API Gateway] GW1 -->|Query| ES[(Elasticsearch)] GW1 -->|Hotel details| CACHE[(Redis Cache)] CACHE -.->|Cache miss| DB1[(PostgreSQL)] end subgraph "Write Path" U2[User] -->|Reserve| GW2[API Gateway] GW2 -->|Create booking| RESV[Reservation Service] RESV -->|Check + Reserve| INV[Inventory Service] INV -->|UPDATE| DB2[(PostgreSQL)] RESV -->|Charge| PAY[Payment Service] PAY -->|API call| PSP[Stripe / VNPay] end subgraph "Async Path" DB2 -.->|CDC / Event| KAFKA[Kafka] KAFKA -.->|Update index| ES KAFKA -.->|Notification| NOTIFY[Email/SMS] KAFKA -.->|Analytics| DW[(Data Warehouse)] end style DB2 fill:#43a047,color:#fff style ES fill:#1e88e5,color:#fff style KAFKA fill:#ff6f00,color:#fff
Aha Moments & Pitfalls — Nhung dieu rut ra
Aha Moments
| # | Insight | Giai thich |
|---|---|---|
| 1 | DB constraint thuong la du | Khong can implement lock phuc tap. CHECK (reserved <= total) + atomic UPDATE la du cho hau het truong hop. DB engine da duoc toi uu cho viec nay |
| 2 | Overbooking la business decision, khong phai bug | Airlines, hotels deu lam viec nay. Cau hinh overbooking percentage la feature, khong phai defect |
| 3 | Inventory caching la nguy hiem | Cache stale inventory → overbooking hoac lost revenue. Inventory nen doc truc tiep tu DB voi proper indexing |
| 4 | Idempotency ngan double charge | Khong co idempotency → client retry → 2 bookings + 2 charges. reservation_id la idempotency key tu nhien |
| 5 | Two-phase reservation la bat buoc | Phai hold phong truoc khi payment. Khong hold → nguoi khac dat mat trong luc dang thanh toan |
| 6 | Hold expiration la critical | Khong co hold expiration → “ghost bookings” chiem inventory mai mai. Background job release expired holds |
| 7 | Queue la giai phap cho flash sale | Serialize requests qua queue → xu ly tuan tu → khong concurrency issue. Trade-off: async UX |
| 8 | Saga pattern cho distributed transaction | Reserve → Pay → Confirm. Moi buoc co compensating action. Khong dung 2PC vi blocking va fragile |
Common Pitfalls
| # | Pitfall | Hau qua | Cach tranh |
|---|---|---|---|
| 1 | Cache inventory va hien thi nhu source of truth | User thay “con phong” nhung dat thi het → bad UX, mat uy tin | Doc inventory tu DB cho availability check, chi cache hotel info |
| 2 | Khong co hold expiration | User tao reservation nhung khong thanh toan → phong bi “giu” mai | Background job release PENDING reservations sau 10-15 phut |
| 3 | Tin gia tu client | Attacker sua gia 5,000,000 VND → 500 VND | Luon tinh gia tren server, KHONG tin request body |
| 4 | Khong co idempotency key | Double booking, double charge khi client retry | Frontend generate reservation_id truoc khi gui request |
| 5 | Lock qua nhieu rows cung luc | Deadlock khi 2 transactions lock cac rows theo thu tu khac nhau | Lock theo thu tu co dinh (sort by date), hoac dung optimistic locking |
| 6 | Single point of failure o Inventory Service | Inventory Service die → toan bo booking die | Multi-instance + DB replication + circuit breaker |
| 7 | Khong co Saga compensating action | Payment fail nhung inventory van bi hold | Moi forward action phai co compensating action tuong ung |
| 8 | Khong partition inventory table | 36.5M records → query cham | Partition theo date (monthly), chi query tuong lai |
Interview Tips
| Cau hoi interviewer co the hoi | Cach tra loi |
|---|---|
| ”Lam sao xu ly 1000 nguoi dat cung 1 phong?” | Trinh bay 3 concurrency approaches, recommend DB constraint + queue cho flash sale |
| ”Neu payment fail giua chung, lam gi?” | Saga pattern voi compensating actions. Release inventory hold, notify user |
| ”Overbooking thi sao?” | La business decision, configurable. Giai thich effective_capacity formula |
| ”Cache inventory duoc khong?” | Giai thich tai sao nguy hiem, chi cache hotel/room info, khong cache real-time inventory |
| ”Lam sao scale?” | Stateless services horizontal scale. Inventory/DB la bottleneck → vertical scale + partitioning + read replicas |
Internal Links
| Link | Lien quan |
|---|---|
| Tuan-07-Database-Sharding-Replication | Inventory table partitioning, DB replication cho read scalability |
| Tuan-11-Microservices-Pattern | Saga pattern, service decomposition, inter-service communication |
| Case-Design-Payment-System | Payment flow chi tiet, PCI-DSS, idempotency pattern |
| Tuan-08-Message-Queue | Kafka cho async processing, queue-based reservation |
| Tuan-06-Cache-Strategy | Cache-aside pattern cho hotel data, tai sao khong cache inventory |
| Tuan-09-Rate-Limiter | Rate limiting chong scraping va booking bot |
| Tuan-14-AuthN-AuthZ-Security | Authentication, authorization cho admin va user |
| Tuan-15-Data-Security-Encryption | Encryption at rest/transit, PII protection |
| Tuan-02-Back-of-the-envelope | Capacity estimation methodology |
| Tuan-13-Monitoring-Observability | Monitoring, alerting, SLA tracking |
Final takeaway: Hotel Reservation System la bai toan concurrency control tren shared inventory. Core problem khong phai scale (QPS thap), ma la accuracy — khong duoc ban qua so phong, khong duoc charge 2 lan, khong duoc mat booking. Ba ky thuat quan trong nhat: DB constraints (chong overbooking), Idempotency (chong double booking), va Saga pattern (chong inconsistency). Master 3 dieu nay, em co the giai quyet bat ky bai toan inventory nao — tu hotel den e-commerce den ticketing.