예약 프로젝트

박태현·2025년 6월 22일

예약 프로젝트

목록 보기
1/10

프로젝트 소개


예약, 결제, 리워드 지급 등 동시성 이슈가 발생할 수 있는 도메인을 직접 구현하며, 상황에 적합한 동시성 전략을 적용하는 것을 목표로 진행한 프로젝트입니다.

  • 예약 생성 시 조건부 UPDATE( 비어 있는 좌석만 원자적으로 선점 )로 동일 좌석에 대한 중복 예약을 방지하고, 멱등성 키( DB unique 제약 기반 선점 )를 적용하여 동일 요청이 반복되더라도 예약이 한 건만 생성되고 동일한 응답이 반환되도록 하였습니다.

  • 예약, 예약 취소, 리워드 지급 과정에서 회원 자원( 크레딧, 리워드 )에 DB 비관적 락을 적용하여 정합성을 보장하고, 예약 취소와 리워드 지급은 상태 체크( 예약 상태, 지급 일자)를 통해 멱등성을 확보하였습니다.

기술 스택


Backend : Kotlin, Spring Boot, Spring MVC, Spring Data JPA, Spring Security

Frontend : React, JavaScript

Database / Cache : MySQL, Redis

Infrastructure : AWS EC2, Docker, Docker Compose

Monitoring : Spring Actuator, Micrometer

Testing : JUnit5, k6

Etc : SMTP (Spring Mail), Outbox Pattern

아키텍처



예약 진행 플로우

대기열 통과 → 좌석 선택(5분) → 결제창 이동 → 좌석 임시 점유(5분) → 결제 성공 → 예약 확정
                                          └─ 취소/만료 → 좌석 반납 → 홈 화면

동시성 이슈


여러 요청이 동시에 동일한 자원에 접근하거나 변경하는 상황에서는 동시성 문제가 발생할 수 있습니다.

비즈니스 로직 내부에 예외 처리를 해두었더라도, 각 요청이 독립적인 트랜잭션으로 처리되면서 모두 정상 수행된 것처럼 보일 수 있습니다. 그 결과 좌석의 중복 예약이나 리워드의 중복 지급과 같은 데이터 정합성 문제가 발생할 수 있습니다.

이번 프로젝트에서는 조건부 UPDATE(좌석 선점), DB 비관적 락(회원 크레딧,리워드), 멱등성(unique 제약 + 상태 체크)을 선택적으로 적용하여 동시성 문제를 해결했습니다. 동시성 제어를 DB 계층에서 보장하여 여러 요청이 동시에 처리되는 상황에서도 데이터 정합성을 유지했습니다

기능 구현


  • 좌석 예약에는 조건부 UPDATE, 크레딧/리워드에는 비관적 락을 적용해 경합 특성에 맞는 동시성 제어 전략을 구현했습니다.

  • 좌석 예약을 Hold → Confirm → Release 구조로 구현하고, HELD 상태와 heldUntil을 이용해 결제 중에도 트랜잭션 없이 좌석을 보호했습니다.

  • 멱등성 키를 활용해 중복 요청을 원자적으로 처리하고, 동일 요청의 재시도 시 저장된 응답을 반환해 이중 결제를 방지했습니다.

  • Transactional Outbox Pattern을 적용해 예약 트랜잭션과 이메일 발송을 분리하고 발송 실패 시 재시도할 수 있도록 구현했습니다.

  • 통합 및 동시성 테스트를 통해 이중 예약 방지, 홀드/확정 경합, 멱등성, 리워드 지급을 검증했습니다.

profile
꾸준하게

0개의 댓글