본문 바로가기

삼분공부/기타

[MySQL] GET_LOCK()을 활용한 동시성 제어 — Spring Boot에서 안전한 주문 번호 생성하기

동시성이 중요한 시스템에서는 "동시에 들어온 요청이 같은 값을 쓰면 안 되는" 상황이 자주 발생합니다. 특히 주문 번호(billNo)를 생성할 때 순서를 보장해야 하는 경우, 단순한 카운트 기반 로직은 예상치 못한 중복 문제를 일으킬 수 있습니다.

이번 글에서는 Spring Boot + MySQL 환경에서 GET_LOCK()을 이용해 이러한 문제를 간단하게 해결하는 방법을 소개합니다.


💥 문제 상황

예를 들어, 아래와 같이 특정 일자의 주문 건수를 카운트해서 billNo를 생성한다고 가정해봅시다:

 
int orderCount = orderRepository.count(storeNo, regDate);
int billNo = orderCount + 1;

✅ 해결 방법: MySQL GET_LOCK() 사용

MySQL은 GET_LOCK()이라는 함수로 사용자 레벨의 락을 지원합니다. 이 락은 같은 키에 대해 한 번에 하나의 세션만 접근할 수 있게 하므로, 안전한 순서 보장이 가능합니다.

 
SELECT GET_LOCK('my_lock_key', 10);        -- 최대 10초까지 락 대기
SELECT RELEASE_LOCK('my_lock_key');        -- 락 해제

 

🎯 장점과 주의사항

✔️ 장점

  • 다른 시스템(Redis 등) 도입 없이도 동시성 제어 가능
  • scmNo와 businessDt 조합으로 범위를 유연하게 분리 가능
  • Spring Boot에 간단하게 통합 가능

⚠️ 주의사항

  • 락 점유 시간은 짧게 유지하는 것이 중요합니다.
  • 락 획득 실패 시 예외 처리나 재시도 로직 필요
  • GET_LOCK()은 MySQL 연결이 끊기면 자동으로 락 해제됨

✅ 마무리

MySQL의 GET_LOCK()은 복잡한 분산락 시스템 없이도 간단히 동시성 문제를 해결할 수 있는 유용한 도구입니다. Spring Boot와 함께 사용하면, 개발자 입장에서 부담 없이 빠르게 안정적인 시스템을 만들 수 있습니다.

고유 번호 생성, 순차적 작업 처리, 동시성 제어가 필요한 로직에 GET_LOCK()을 도입해보세요.