동시성이 중요한 시스템에서는 "동시에 들어온 요청이 같은 값을 쓰면 안 되는" 상황이 자주 발생합니다. 특히 주문 번호(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()을 도입해보세요.
'삼분공부 > 기타' 카테고리의 다른 글
[Linux] 리눅스 파일 관련 명령어 총정리 (0) | 2025.04.03 |
---|---|
[Git] You have not concluded your merge (MERGE_HEAD exists). hint: Please, commit your changes before merging. Exiting because of unfinished merge. (0) | 2025.04.01 |
[SQL] MySQL Slow Query Log 설정과 활용법 (0) | 2025.03.26 |
[Git] 프로젝트 수정 중 깃 원격 저장소 주소 변경 시 ! (0) | 2025.02.12 |
[Linux] 리눅스 실시간 로그 명령어 정리 (0) | 2025.02.11 |