reservation-demo/README.md

87 lines
2.9 KiB
Markdown

# reservation-demo
공연 예약을 위한 Spring Boot 백엔드 API입니다. 주최사의 공연 등록, 회차별 좌석 재고 관리, 사용자 예약 및 취소 기능을 제공합니다.
## Runtime, Library
- Java 21
- Spring Boot 4
- Spring Data JPA
- Spring Security + JWT
- MySQL 8
- Flyway
- SpringDoc OpenAPI
- Testcontainers
## 패키지 구조
```
com.reservation.demo
├── api/
│ ├── auth/
│ ├── concert/
│ ├── organizer/
│ └── reservation/
├── config/ # 설정
├── domain/ # JPA Entity, Enum
│ ├── concert/
│ ├── reservation/
│ ├── seat/
│ └── user/
├── repository/ # Spring JPA
├── service/ # 비즈니스 로직
└── common/ # 예외 처리, Security 유틸
```
## API
| Method | URL | 권한 | 설명 |
|--------|-----|------|------|
| POST | `/api/v1/auth/signup` | Public | 회원가입 |
| POST | `/api/v1/auth/login` | Public | 로그인 |
| GET | `/api/v1/concerts` | Public | 공연 목록 |
| GET | `/api/v1/concerts/{concertId}` | Public | 공연 상세 |
| GET | `/api/v1/concerts/performances/{performanceId}/seats` | Public | 좌석 맵 |
| POST | `/api/v1/organizer/concerts` | ORGANIZER | 공연 등록 |
| POST | `/api/v1/reservations` | USER | 예약 생성 |
| POST | `/api/v1/reservations/{id}/cancel` | USER | 예약 취소 |
| GET | `/api/v1/reservations/me` | USER | 내 예약 목록 |
## 스키마
테이블명은 DB 그대로이며, 선 위 한글은 관계 설명용입니다 (코드/컬럼명 아님).
```mermaid
erDiagram
users ||--o{ concerts : "주최"
users ||--o{ reservations : "예약"
concerts ||--o{ performances : "회차"
concerts ||--o{ seats : "좌석 정의"
performances ||--o{ seat_inventories : "회차별 재고"
seats ||--o{ seat_inventories : "좌석 매핑"
performances ||--o{ reservations : "예약 대상"
reservations ||--o{ reservation_items : "예약 상세"
seat_inventories ||--o| reservation_items : "좌석 점유"
```
## 동시성 설계
### 문제
인기 공연 오픈 시, 여러 사용자가 동일 좌석에 동시 예약하면 중복 예약이 발생할 수 있습니다.
### 현재 해결 전략
1. DB Unique Constraint — `seat_inventories(performance_id, seat_id)` UNIQUE
2. 비관적 락 — `SeatInventoryRepository.findAllByIdInForUpdate()`
3. 좌석 ID 정렬 후 락 — 데드락 방지
4. 단일 트랜잭션 — 좌석 상태 변경 + Reservation / ReservationItem 생성
### 트레이드오프
| 방식 | 장점 | 단점 |
|------|------|------|
| 비관적 락 (현재) | 구현 단순, 정합성 강함 | 동시성 높을 때 DB 부하 (row 경합) |
| 낙관적 락 | 읽기 성능 좋음 | 충돌 시 재시도 로직 필요 |
| Redis 선점 | DB 부하 분산 | 인프라 복잡도 증가, Mysql과 Redis 트랜잭션 처리 불가|