https://github.com/Banhklo2/coffee-order-system.git
GitHub - Banhklo2/coffee-order-system: Spring Boot 포인트 기반 커피 주문 결제 시스템
Spring Boot 포인트 기반 커피 주문 결제 시스템. Contribute to Banhklo2/coffee-order-system development by creating an account on GitHub.
github.com
☕ Coffee Order System
설계대로 구현해보니 보였던 문제들과 개선 과정
📌 들어가며
이번 프로젝트는 도메인 설계와 비즈니스 규칙을 먼저 정의한 뒤 구현을 시작했다.
하지만 실제 구현을 진행하면서
설계 단계에서는 보이지 않았던 문제들을 마주하게 되었고,
그 과정에서 여러 개선을 적용하게 되었다.
이번 글에서는 구현 과정에서 겪었던 문제와 해결 과정 중심으로 정리해보려고 한다.
🧠 설계에서 고려했던 기술적 포인트, 그리고 실제 구현
프로젝트를 시작할 때 다음과 같은 기술적 고려사항을 정리했었다.
- 트랜잭션을 통한 데이터 정합성 보장
- 포인트 차감 시 동시성 제어
- 인기 메뉴 집계 성능 문제
- 외부 플랫폼 전송 구조 분리
구현을 진행하면서 이 고민들이 실제로 어떻게 드러났는지 정리해보면 다음과 같다.
1. 트랜잭션 → “필수 조건”이었다
설계 단계에서는 주문 생성, 포인트 차감, 결제 저장을
하나의 트랜잭션으로 처리해야 한다고 생각했다.
구현을 진행하면서 확인해보니 이건 선택이 아니라 필수였다.
조금만 로직을 분리해도 다음과 같은 문제가 발생할 수 있었다.
- 주문만 생성되는 경우
- 포인트만 차감되는 경우
⭐ 결국 설계에서 생각한 대로 하나의 트랜잭션으로 묶는 것이 필수였다.
2. 외부 플랫폼 전송 → 구조 분리가 핵심이었다
설계 단계에서는 외부 플랫폼 전송을 주문 로직과 분리해야 한다고 생각했다.
처음에는 @Async를 사용해 비동기 처리했지만,
트랜잭션과 분리되지 않아 롤백 상황에서도 외부 API가 호출될 수 있는 문제가 있었다.
이를 해결하기 위해 다음과 같은 구조로 개선했다.
- 이벤트 발행
- AFTER_COMMIT 기반 이벤트 처리
- 비동기 실행
⭐ 단순 비동기 처리가 아니라 트랜잭션과 외부 로직을 분리하는 것이 핵심이었다.
🔗 관련 글
2026.03.31 - [트러블슈팅] - 주문 완료 후 외부 전송을 이벤트 기반으로 분리하며 겪은 문제
주문 완료 후 외부 전송을 이벤트 기반으로 분리하며 겪은 문제
2026.03.31 - [트러블슈팅] - 외부 API 호출 비동기 처리 적용 (@Async) 외부 API 호출 비동기 처리 적용 (@Async)2026.03.31 - [트러블슈팅] - 외부 플랫폼 주문 전송 기능 - Mock API 구현 외부 플랫폼 주문 전송
sudaruuu.tistory.com
3. 동시성 → 예상이 아니라 실제 문제였다
설계 단계에서는 "동시성 문제가 발생할 수 있다" 정도로 생각했다.
하지만 테스트를 진행하면서 이 문제가 실제로 발생할 수 있음을 확인했다.
특히 포인트 차감 로직에서 동시에 요청이 들어오면
둘 다 성공하는 문제가 발생할 수 있었다.
→ 비관적 락 (Pessimistic Lock)을 적용하여 해결
⭐ 동시성 문제는 고려가 아니라 반드시 해결해야 하는 문제라는 것을 느꼈다.
🔗 관련 글
2026.04.01 - [트러블슈팅] - 포인트 차감 동시성 문제 해결 - 비관적 락 적용
포인트 차감 동시성 문제 해결 - 비관적 락 적용
2026.03.27 - [Spring 2기 과제] - 포인트 기반 커피 주문 결제 시스템 (도메인 설계) 포인트 기반 커피 주문 결제 시스템 (도메인 설계)https://github.com/Banhklo2/coffee-order-system.git GitHub - Banhklo2/coffee-order-syst
sudaruuu.tistory.com
4. 인기 메뉴 집계 → 인덱스만으로는 부족했다
초기 설계에서는 단순 집계 쿼리로 구현하고
필요 시 캐시를 도입하기로 했다.
실제로 구현하면서 먼저 인덱스를 적용해 DB 조회 성능은 개선되었다.
하지만 인덱스는 조회 속도를 개선할 뿐,
요청 자체가 많아지는 상황에서는 여전히 DB를 계속 조회해야 한다는 한계가 있었다.
그래서 Redis 캐싱을 추가로 적용했다.
- 인덱스 → DB 조회 성능 최적화
- 캐싱 → DB 접근 자체 감소
⭐ 두 가지는 역할이 완전히 다르다는 것을 이해하게 되었다.
🔗 관련 글
2026.04.02 - [트러블슈팅] - 인덱스 적용 이후에도 느렸던 이유 - 캐싱 도입
인덱스 적용 이후에도 느렸던 이유 - 캐싱 도입
2026.04.01 - [트러블슈팅] - 인기 메뉴 조회 성능 개선 - 인덱스 도입 인기 메뉴 조회 성능 개선 - 인덱스 도입2026.03.27 - [Spring 2기 과제] - 포인트 기반 커피 주문 결제 시스템 (도메인 설계) 포인트 기
sudaruuu.tistory.com
5. 테스트 코드 → 검증의 필요성을 느끼게 된 순간
초기에는 Postman을 통해 API 테스트를 진행하며 정상 동작을 확인했다.
하지만 다음과 같은 한계를 느꼈다.
- 성공 케이스 위주의 검증
- 예외 상황 테스트 어려움
- 서비스 내부 로직 흐름 검증 불가
- 동일 조건 반복 테스트 어려움
특히 여러 로직이 함께 실행되는 경우, 정확한 동작을 확신하기 어려웠다.
그래서 서비스 레이어 테스트 코드를 작성하여
비즈니스 로직을 코드 수준에서 직접 검증했다.
특히 Mockito를 활용해 이벤트 발행과 DB 호출 여부까지 함께 검증했다.
⭐ "동작 확인"이 아니라 "정상 동작 검증"이 중요하다는 것을 느꼈다.
🔗 관련 글
2026.04.03 - [트러블슈팅] - Postman 테스트를 넘어 서비스 레이어 검증하기
Postman 테스트를 넘어 서비스 레이어 검증하기
문제 상황기능 구현이 끝났다고 해서, 정말로 로직이 정상적으로 동작한다고 확신할 수 있을까? 기능 구현 이후 Postman을 통해 API를 테스트하며정상 동작 여부를 확인하고 있었다. 하지만 다음과
sudaruuu.tistory.com
💡 정리
설계 단계에서 정리했던 기술적 고려사항들은 단순한 이론이 아니라 실제 구현 과정에서 반드시 마주하게 되는 문제들이었다.
설계는 방향을 잡아주고, 구현은 그 설계를 검증하는 과정이라는 것을 느꼈다.
⭐ 좋은 설계는 구현을 통해 검증되고, 그 과정에서 완성된다 !!
'Spring 2기 과제' 카테고리의 다른 글
| 포인트 기반 커피 주문 결제 시스템 (API 명세서 개선) (0) | 2026.03.30 |
|---|---|
| 포인트 기반 커피 주문 결제 시스템 (API 명세서) (0) | 2026.03.27 |
| 포인트 기반 커피 주문 결제 시스템 (도메인 설계) (0) | 2026.03.27 |
| [Spring 2기 과제] CH5 배고팡 프로젝트 + KPT 회고 (0) | 2026.03.25 |
| [Spring 2기 과제] CH5 플러스 Spring 과제 + 트러블슈팅 (0) | 2026.02.27 |