전체 예매 프로세스 흐름도
핵심: 대기열 → 좌석 선택(눈으로만) → 결제하기 버튼(이때 락!)
1단계: 대기열 진입 (문지기)
사용자가 공연 상세 페이지에서 [예매하기] 버튼을 누름
- 바로 좌석표가 나오지 않고 대기 화면 뜸 → 대기열 진입: POST /api/v1/queue/enter
- 현재 대기 50명... 10명..." 이렇게 순번을 확인 → 대기중 (Polling):GET /api/v1/queue/{queueId}
- 좌석 선택 페이지
- 나의 상태가 READY가 되면 입장 가능 → POST /api/v1/queue/{queueId}/enter를 호출하여 입장(SessionId)
2단계: 좌석 선택 (눈치 게임)
좌석 배치도에서 좌석 선택
- 좌석 조회: GET /api/v1/schedules/{id}/seats
- 사용자가 화면에서 A1, A2 좌석을 클릭
- 이때는 서버에 아무런 요청을 보내지 않음 (단순 프론트엔드 상태)
- 즉, 내가 A1을 찍고 있어도, 아직 내 것이 아님
- 좌석 클릭 (UI):
3단계: 결제하기 버튼 클릭 (진검 승부)
사용자가 좌석을 다 고르고 [결제하기] 버튼을 누르는 순간 서버 API가 호출됩니다.
- 이 API 하나가 "좌석 락(Lock) + 예매 데이터 생성 + 결제 준비"를 한 번에 처리합니다.
- API 호출: POST /api/v1/reservations
[시나리오: 사용자 A vs 사용자 B]
상황: 둘 다 A1 좌석을 보고 있고, 거의 동시에 [결제하기]를 눌렀습니다.
- 사용자 A (0.1초 빠름):
- 서버: "A1 좌석 락(Lock) 성공!"
- 결과: 200 OK 응답을 받고 토스 결제창으로 넘어갑니다.
- 사용자 B (0.1초 느림):
- 서버: "어? A1 좌석은 방금 A가 락 걸었는데?"
- 결과: 409 Conflict 에러 발생.
- 응답 메시지: "선택하신 좌석이 이미 예약되었습니다".
- 사용자 B의 화면 처리:
- 프론트엔드: 에러 메시지를 alert으로 띄워줍니다.
- 새로고침: 좌석 선택 페이지를 새로고침(또는 리로드)하여, A1이 이미 나갔다는(SOLD/LOCKED) 최신 상태의 좌석표를 다시 보여줍니다.
설계 시 주의할 점
- DB 스키마 관점:
- POST /reservations 요청이 들어오면, DB(또는 Redis)에서 해당 좌석이 이미 선점(PENDING)되었거나 판매(SOLD)되었는지 확인하는 로직이 가장 중요합니다.
- 앞서 설계한 ReservationSeat 엔티티가 생성되기 전에 이 검증이 먼저 수행되어야 합니다.
- 트랜잭션:
- 여러 좌석을 선택했을 때 (예: A1, A2), 하나라도 이미 선점되어 있으면 전체 실패(All or Nothing) 처리해야 합니다. A1은 성공하고 A2는 실패하는 상황은 없습니다.
'Projects > Side Project' 카테고리의 다른 글
| [V2]동시에 예매를 눌렀을 때, 서버는 살아남을 수 있을까? — 부하 테스트와 트랜잭션 최적화 기록 (0) | 2026.02.28 |
|---|---|
| [Project] 공연 예매 시스템 대용량 트래픽 대응기: 해결 방안 설계 (V1 → V2) (0) | 2026.02.03 |
| 대규모 트래픽 좌석 예매 시스템 설계_대기열, Redis (0) | 2025.12.19 |
| [토이]데이터 마스킹/감사 라이브러리 회고: Masking Library (4) | 2025.07.09 |
| [Project01]설문조사 서비스 요구사항 및 설계 (2) | 2025.06.15 |