[프로젝트 회고] 펜션 예약 홈페이지 개발과 예약 동시성 제어
들어가며
2024년 하반기 현장실습에서 펜션 예약 홈페이지를 개발했다.
이 프로젝트는 내게 꽤 큰 의미가 있었다. 학교에서 공부하던 개발과 실제 서비스에 가까운 개발은 달랐다.
특히 예약과 결제처럼 데이터가 틀어지면 바로 서비스 신뢰도에 영향을 주는 기능을 다루면서, 백엔드 개발에서 안정성이 왜 중요한지 체감했다.
기술 스택은 React, Axios, Tailwind CSS, Java 17, Spring Boot, MySQL, OAuth2.0을 사용했다.
프론트엔드와 백엔드를 함께 구현했고, 사수분의 피드백을 받으며 기능을 정리해나갔다.
프로젝트에서 맡은 역할
이 프로젝트에서는 기획과 개발을 함께 진행했다.
주요 작업은 다음과 같았다.
- 펜션 예약 홈페이지 화면 구현
- React 기반 UI 구성
- Axios를 이용한 비동기 통신 처리
- Spring Boot 기반 REST API 개발
- MySQL 기반 DB 설계
- OAuth2.0 로그인 흐름 구현
- 예약/결제 관련 예외 처리
- 예약 중복 방지를 위한 트랜잭션과 동시성 제어
처음에는 화면을 만들고 API를 붙이는 것도 큰 작업처럼 느껴졌다.
하지만 프로젝트를 진행하면서 가장 어렵고 중요했던 부분은 예약 데이터의 무결성을 지키는 일이었다.
예약 도메인의 어려움
예약 기능은 단순 CRUD와 달랐다.
사용자가 같은 날짜와 같은 객실을 동시에 예약하려고 할 수 있다.
이때 서버가 단순히 “현재 예약이 없으면 저장”하는 방식으로 동작하면, 거의 동시에 들어온 요청이 모두 성공할 가능성이 있다.
예를 들어 이런 상황이다.
- A 사용자가 12월 31일 객실 예약 요청을 보낸다.
- B 사용자도 거의 동시에 같은 객실 예약 요청을 보낸다.
- 두 요청 모두 “예약 없음”으로 판단한다.
- 둘 다 예약 저장에 성공한다.
이렇게 되면 중복 예약이 발생한다.
예약 서비스에서 중복 예약은 치명적인 문제다.
사용자 경험도 망가지고, 운영자 입장에서도 신뢰를 잃을 수 있다.
그래서 예약 기능에서는 트랜잭션과 동시성 제어가 꼭 필요했다.
비관적 락과 트랜잭션
처음에는 애플리케이션 레벨에서 예약 가능 여부를 확인하면 충분하지 않을까 생각했다.
하지만 동시에 여러 요청이 들어오는 상황에서는 단순 조회만으로 안전하지 않았다.
그래서 예약 가능 여부를 확인하는 시점부터 다른 트랜잭션이 같은 데이터를 수정하지 못하도록 비관적 락을 적용하는 방향을 잡았다.
JPA의 Native Query를 사용해 직접 쿼리를 작성했고, 조회 시점부터 해당 행에 lock을 걸어 트랜잭션이 끝날 때까지 다른 요청이 끼어들지 못하도록 했다.
또한 예약 로직에는 트랜잭션을 적용해 하나의 흐름으로 묶었다.
1
2
3
4
5
6
@Transactional
public Reservation createReservation(...) {
// 예약 가능 여부 확인
// 예약 데이터 생성
// 결제 흐름 처리
}
상황에 따라 격리 수준도 함께 고민했다.
예약과 결제처럼 민감한 도메인에서는 성능보다 데이터 정합성을 우선해야 하는 순간이 있다.
예외 처리의 중요성
예약과 결제는 실패할 수 있는 경우가 많다.
- 이미 예약된 객실
- 존재하지 않는 객실
- 잘못된 날짜
- 결제 실패
- 사용자 인증 실패
- 네트워크 문제
이런 상황에서 서버가 모호한 에러를 반환하면 프론트엔드는 사용자가 이해할 수 있는 안내를 하기 어렵다.
그래서 예외를 최대한 명확하게 나누고, 프론트엔드가 상황에 맞게 처리할 수 있도록 응답 구조를 고민했다.
이 경험은 이후 JWT 인증 예외 처리나 프로젝트 API 설계에서도 계속 영향을 주었다.
프론트엔드 구현 경험
이 프로젝트에서는 프론트엔드도 함께 구현했다.
React와 Tailwind CSS를 사용했고, Axios로 백엔드 API와 통신했다.
Cursor AI와 v0 같은 도구를 활용해 UI 구성 시간을 줄이기도 했다.
처음에는 프론트엔드가 단순히 화면을 만드는 영역이라고 생각했지만, 직접 구현해보니 백엔드 API 설계와 매우 밀접하게 연결되어 있었다.
API 응답이 애매하면 화면에서 처리하기 어렵고, 에러 코드가 불명확하면 사용자에게 어떤 메시지를 보여줘야 할지 모호해진다.
이 경험 덕분에 이후 백엔드 API를 만들 때 프론트엔드가 사용하기 쉬운 구조를 더 생각하게 되었다.
배운 점
이 프로젝트에서 가장 크게 배운 것은 데이터 무결성의 중요성이었다.
특히 예약과 결제는 사용자의 돈과 일정이 걸린 기능이다.
데이터가 한 번 틀어지면 단순 버그가 아니라 서비스 신뢰도 문제로 이어진다.
또한 트랜잭션은 단순히 @Transactional을 붙이는 것이 아니라, 어느 범위까지 하나의 작업으로 묶을지 고민해야 한다는 것을 배웠다.
동시성 제어도 마찬가지다.
락을 걸면 안전해질 수 있지만, 성능 비용도 생긴다. 그래서 어떤 도메인에서 어떤 수준의 안정성이 필요한지 판단하는 것이 중요했다.
마무리
펜션 예약 홈페이지 프로젝트는 내가 백엔드 개발자로서 중요하게 생각하는 방향을 잡게 해준 경험이었다.
안정적인 구조, 신뢰할 수 있는 데이터 처리, 명확한 예외 처리.
이 세 가지가 이후 프로젝트를 할 때도 계속 기준이 되었다.
당시에는 부족한 점도 많았지만, 예약과 결제라는 민감한 도메인을 직접 다뤄본 덕분에 백엔드 개발이 단순 기능 구현을 넘어 서비스 신뢰를 지키는 일이라는 것을 배울 수 있었다.
Leave a comment