[항해 플러스 Lite 1기] 5주차 - DB Lock 기반 동시성 제어
데이터베이스 락 기반 동시성 제어
이번 주차에서 얻어가고 싶은 것
동시성 문제가 발생하는 원인을 깊이 이해하고, 그에 대한 효과적인 대응 전략으로서의 DB 락 기반 제어 방식을 익히고 싶다.
단순히 "동시성 제어가 필요하다"는 수준을 넘어서, 어떤 방식이 언제 적절한지 구체적으로 판단하고 설계할 수 있는 능력을 키우고 싶다.
과제 요구사항
- 동시성 문제 식별(포인트 충전/사용, 쿠폰 발급, 주문 재고 처리 등)
- DB 락 전략(낙관적 락, 비관적 락)의 적용 비교
- 테스트 환경에서 동시 요청을 시뮬레이션하여 실제 문제 재현 및 해결
문제 상황
(1) 선착순 쿠폰 발급 과정에서 동시성 문제가 발생했다. 재고가 남아 있음에도 불구하고 중복 발급되거나, 재고보다 많은 쿠폰이 발급되는 문제가 발생했다. 주문 시 상품 재고 차감에서도 마찬가지의 문제가 발생했다.
(2) Java 코드 내 synchronized, ReentrantLock 등을 활용해보았지만, 이는 단일 인스턴스에서만 효과가 있어 분산 환경에서는 무력해진다는 문제점이 있었다.
(3) 결국 DB 차원에서의 락 제어가 필요하다는 판단을 하게 되었다.
시도
(1) 먼저 비관적 락(Pessimistic Lock)을 고려했다. SELECT ... FOR UPDATE 쿼리를 통해 동시에 접근하는 트랜잭션이 존재할 경우 락을 걸어 직렬화 처리를 유도했다.
(2) 이후 낙관적 락(Optimistic Lock) 방식도 적용해보았다. JPA에서 @Version 필드를 활용해, 트랜잭션 충돌 시 OptimisticLockingFailureException이 발생하도록 했다.
(3) 실험적으로, 동시 요청을 다수 발생시키는 테스트 코드를 작성하고, 각각의 락 방식에서 발생하는 현상들을 비교해보았다.
해결
(1) 비관적 락을 적용한 경우, 정합성은 확보되었지만 성능 저하가 눈에 띄게 발생했다. 특히 대기 시간이 늘어나면서 전체 처리 속도가 느려지는 단점이 있었다.
(2) 낙관적 락을 적용한 경우, 성능은 유지되었으나 충돌이 빈번할 경우에는 재시도가 필요해 복잡도 증가라는 이슈가 있었다. 이를 보완하기 위해 재시도 로직에 대해 추가 설계를 진행했다.
(3) 애플리케이션 수준의 JUnit5와 멀티 쓰레드를 활용한 테스트 외에도 성능 테스트를 위해 k6 부하 테스트를 진행하여 결과를 확인했다.
(4) 상황에 따라 두 락 전략을 적절히 조합해서 사용하는 방안을 고민하고 있다. 예를 들어, 트래픽이 낮은 시간대에는 낙관적 락, 트래픽이 급증하는 특정 이벤트 시간대에는 비관적 락으로 전환하는 방식 등.
알게된 것
- 동시성 제어는 상황에 따라 전략을 달리 해야 한다는 것을 체감했다. 정답은 없고, 각 전략마다의 장단점이 명확하다는 점이 핵심이다.
- 단일 인스턴스에서는 애플리케이션 레벨의 락도 가능하지만, 분산 환경에서는 결국 DB 또는 외부 시스템 기반의 제어가 필수라는 것을 알게 되었다.
- 락 전략뿐만 아니라, 재시도 로직, 에러 핸들링, 로그 추적 등 다양한 부수 요소들이 함께 설계되어야 실질적인 안정성을 보장할 수 있다.
아쉬운 점
락을 걸어 동시성 문제를 해결하는 것은 결국 처리량 감소와 직결된다. 모든 상황에서 락이 정답은 아니라는 점도 함께 깨달았다.
락 없이도 처리 가능한 구조나, 이벤트 기반으로 동기화를 분리하는 등의 아키텍처적 개선도 함께 고민해볼 필요가 있다.
또 이번에 JPA 연관관계로 인해 testcontainers 실행 과정에서 DDL 순서로 인해 오류가 많이 발생했다. 그래서 어쩔 수 없이 일단은 연관관계를 잠시 block 해두었는데, 이를 근원적으로 해결할 수 있는 방안을 꼼꼼하게 고민해보지 못했다. 그래서 참 테스트는 매 주 하지만 쉽지 않다는 것을 느꼈다.
다음 주차 목표
락 기반 제어 외에도, 큐잉 시스템(Redis, Kafka)이나 Token Bucket, Semaphore 등의 동시성 제어 전략도 함께 실험해보며, 보다 다양한 선택지를 경험해보자.
항해플러스 Lite 백엔드 2기 모집이 시작되었습니다!
관심있는 분들께서는 아래 페이지 읽어보시고 등록하실 때 아래 코드 입력하시면 10만원 추가 할인을 받으실 수 있습니다!
과정 상 궁금하신 내용은 댓글 남겨주시고 추후 후기를 남길 예정이니 참고하셔도 좋습니다 :)
추천인 코드: o3HXzU
항해 플러스 Lite 백엔드 코스
바쁜 개발자를 위한 1인 부트캠프, 내 일정에 맞춰 꾸준히 학습해요.
hanghae99.spartacodingclub.kr