docs: add README with API spec, schema diagram, and concurrency design
This commit is contained in:
parent
6fda098137
commit
8539dc105b
1 changed files with 87 additions and 0 deletions
87
README.md
Normal file
87
README.md
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
# 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 트랜잭션 처리 불가|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue