TIL - Spring Boot에서 동시성 제어 : 언제 무엇을 써야 할까?

J_log·2025년 5월 30일
0
post-thumbnail

예전에 Lock에 대해 공부하면서 동시성 제어라는 말을 접했었다. 하지만 동시성 제어를 할 수 있는 방법으로는 많은 방법이 있고 어떤 상황에 어떻게 대처해야 될지 의문점이 생겨 공부한 내용을 정리해 보려고한다.

동시성 문제는 실제 서비스에서 생각보다 흔하게 발생한다. 특히 재고 감소, 결제, 좋아요 등의 기능은 수많은 요청이 동시에 들어올 수 있기 때문에 신중한 동시성 제어가 필요하다.

동시성 문제란?

동시에 여러 사용자가 같은 자원에 접근할 때, 예상치 못한 상태 충돌이나 데이터 불일치가 발생하는 문제이다.
예를 들어 A와 B가 동시에 같은 상품의 재고를 감소시키면, 잘못된 재고 값이 저장될 수 있다.

주요 동시성 제어 방법

방식범위장점단점추천 상황
synchronizedJVM 내 단일 인스턴스구현 매우 쉬움분산 환경에서는 무용지물단일 서버에서 간단한 테스트나 개발용 동기화
@Transactional + Pessimistic LockDB충돌 방지 확실성능 저하, 데드락 가능충돌이 자주 발생하는 환경 (ex. 재고, 결제)
@Transactional + Optimistic LockDB락 없이 동시성 제어, 성능 우수충돌 시 예외 처리 및 재시도 로직 필요충돌이 드문 상황 (ex. 게시글 좋아요)
Redis 분산 락 (Redisson)분산 서버 전체서버 여러 대에서 일관성 유지 가능Redis 장애 시 전체 시스템 영향분산 환경에서 강한 락 필요 (ex. 결제, 이벤트 선착순 등)
Kafka / MQ 직렬 처리분산 서버 전체완전한 순차 처리 가능실시간성 떨어짐, 큐 지연 발생 가능순서가 중요한 작업 (ex. 포인트 적립, 거래 내역 저장)

왜 한 가지 방식으로 통일하지 않을까?

"Redisson이 분산 락도 되는데 이걸로 다 하면 되지 않을까?" 라는 생각이 들 수 있지만, 실제로는 성능, 안정성, 구현 난이도를 고려해 상황에 맞는 전략을 선택하는 것이 훨씬 중요하다.

Redisson만으로는 부족하거나 과한 경우

  • 단순한 동기화인데 Redis 락을 사용하면 오히려 성능 낭비
  • 충돌이 거의 없는데 굳이 락을 걸 필요는 없다
  • 외부 장애 (예 : Redis 다운)로 전체 시스템이 영향을 받을 수 있다

결론

모든 락은 비용이 따르고, 트레이드오프가 존재한다.
따라서 서비스의 특성과 요구 사항에 따라 가장 효율적인 전략을 선택해야 한다.

0개의 댓글