삼분공부/DataBase
[MySQL] GET_LOCK()을 활용한 동시성 제어 — Spring Boot에서 안전한 주문 번호 생성하기
케이쓰리
2025. 4. 1. 14:07
동시성이 중요한 시스템에서는 "동시에 들어온 요청이 같은 값을 쓰면 안 되는" 상황이 자주 발생합니다. 특히 주문 번호(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()을 도입해보세요.
반응형