동시성 처리를 위한 락의 종류 정리 ✨
동시성 처리는 서버 개발자라면 반드시 마주치는 문제다. 여러 트랜잭션이 동시에 같은 자원에 접근할 때, 데이터 정합성을 보장하기 위해 다양한 락(lock) 전략이 쓰인다. 이번 글에서는 DB 레벨과 애플리케이션 레벨에서 활용할 수 있는 대표적인 락의 종류를 정리해본다.
🔒 DB 레벨 락(비관적 락 = 베타락)
- “동시성 충돌을 미리 막기 위해 DB 차원에서 걸어두는 락”이라는 개념
1. 레코드 락 (Record Lock)
- 특정 row(인덱스 레코드)에 걸리는 락
- UPDATE, DELETE, SELECT ... FOR UPDATE 시 발생
- PK/Unique 조건 단건 조회 → 해당 row만 잠김
👉 예: SELECT * FROM product WHERE id=1 FOR UPDATE;
2. 갭 락 (Gap Lock)
- row와 row 사이의 빈 공간(갭)에 거는 락
- 새로운 row insert를 막기 위해 사용
- 주로 범위 조회 시 발생
👉 예: SELECT * FROM product WHERE price BETWEEN 100 AND 200 FOR UPDATE;
→ 이 구간에 새로운 row가 삽입되지 않도록 막음
3. 넥스트 키 락 (Next-Key Lock)
- 레코드 락 + 갭 락
- 즉, row 자체와 그 앞뒤 구간까지 잠금
- Phantom Read 방지 목적
- 단건 조회(PK/Unique) → 레코드 락만
- 범위 조회(non-unique, range) → 넥스트 키 락 발생
💡 Application 레벨 락
4. 낙관적 락, Optimistic Lock
- DB 물리적 락이 아님
- 애플리케이션에서 동시성 제어 전략으로 활용
- 보통 version 컬럼(혹은 timestamp)을 사용
- Update 시 WHERE id=? AND version=? 조건을 체크
→ version이 다르면 update 실패 → 충돌 발생 → 재시도 필요
👉 장점: DB에 물리적 락을 걸지 않아 성능상 유리
👉 단점: 충돌 발생 시 재시도 로직 필요
✨ 핵심 포인트
- SELECT ... FOR UPDATE
- 단건 조회 → 레코드 락
- 범위 조회 → 넥스트 키 락
- Insert 시 충돌 → 갭 락/넥스트 키 락 때문에 새로운 row 추가가 막힘
- 베타락(낙관적 락) = DB 락과 별개, 애플리케이션에서 version 필드로 제어
🚀 Insert 시 취할 수 있는 전략
- 유니크 제약조건 활용
- 예: (product_id, user_id)를 유니크 키로 두면 중복 Insert 방지
- 소프트 딜리트를 함께 쓴다면 (product_id, user_id, delYn) 조합 유니크로 설계 가능
🌐 분산 환경에서의 선택지
- Redis 분산 락
분산 서버 환경에서는 DB 락만으로는 한계가 있다. 이때는 Redis 기반의 분산 락을 활용해 여러 서버 간 동시성 제어를 할 수 있다.
🧪 앞으로 테스트해볼 것
- 동일한 동시성 처리 환경에서 다음 락들의 성능 차이 비교
- DB 레코드 락
- 넥스트 키 락
- 낙관적 락 (베타락)
- Redis 분산 락
- 시나리오 예: 상품 재고 관리에서 동시에 주문이 들어올 때, 어떤 방식이 가장 효율적일까?
마무리 💭
동시성 제어는 단순히 "락을 걸자"의 문제가 아니다.
- DB 레벨 락은 안전하지만 범위가 넓을수록 성능 저하가 발생할 수 있다.
- **애플리케이션 레벨 락(베타락)**은 충돌 감지를 통해 성능을 확보할 수 있지만 재시도 로직이 필요하다.
- 분산 락은 마이크로서비스/멀티 서버 환경에서 사실상 필수다.
👉 결국 중요한 건 서비스 상황에 맞는 전략을 선택하는 것이다.
'개발' 카테고리의 다른 글
| MVVM 구조로 리팩토링 (0) | 2025.10.10 |
|---|---|
| 동시성 제어 실험기: Optimistic vs Pessimistic vs Redis Lock (0) | 2025.09.21 |
| 비동기 PDF 합성에서 트랜잭션 전파 실패 보완하기 (2) | 2025.08.05 |
| 메모리 성능 개선기 (2) | 2025.07.24 |
| 동의서 pdf 합성 성능 개선 (1) | 2025.07.21 |