본문 바로가기
IT

낙관적 락 vs 비관적 락

by urosie 2025. 12. 15.
반응형

1. 동시성 문제의 본질

하나의 버튼 클릭이더라도
같은 데이터를 여러 사용자가 동시에 수정할 수 있다.
이때 중복 승인, 덮어쓰기, 상태 꼬임이 발생한다.

이걸 막는 방법이 락(lock) 이다.


2. 낙관적 락 (Optimistic Lock)

개념

  • 충돌은 자주 발생하지 않는다는 가정
  • 먼저 락을 걸지 않는다
  • 업데이트 시점에만 충돌 여부를 검사

핵심 메커니즘

  • row에 VERSION 컬럼을 둔다
  • 업데이트 시 “내가 읽은 버전이 아직 유효한지” 확인
 
UPDATE loan SET status = 'APPROVED', version = version + 1 WHERE id = 1 AND version = 3;
  • 성공(1 row) → 정상 처리
  • 실패(0 row) → 누군가 먼저 수정함

특징

  • DB 락을 오래 잡지 않음
  • 성능 좋음
  • 충돌 시 재시도 또는 에러 처리 필요

적합한 경우

  • 승인/거절
  • 게시글 수정
  • 대부분의 웹 서비스

3. 비관적 락 (Pessimistic Lock)

개념

  • 충돌이 자주 발생한다고 가정
  • 아예 처음부터 다른 트랜잭션 접근 차단

구현 예

 
SELECT * FROM loan WHERE id = 1 FOR UPDATE;
  • 트랜잭션 종료까지 row 락 유지

특징

  • 중복 처리 확실히 방지
  • 락 대기, 데드락 위험
  • 트래픽 많으면 성능 저하

적합한 경우

  • 재고 차감
  • 계좌 이체
  • 실시간 금액 변경

4. VERSION이란 무엇인가

정의

row가 몇 번째로 수정되었는지를 나타내는 값

  • 업무 의미 없음
  • 단순 증가
  • 사람이 해석하지 않음
 
version = 1 → 최초 version = 2 → 첫 수정 version = 3 → 두 번째 수정

중요한 점

  • JPA 전부터 존재하던 오래된 패턴
  • JPA는 자동화했을 뿐, 개념을 만든 게 아님

5. VERSION은 어떻게 중복을 막는가

  1. A, B가 동시에 조회 (version = 3)
  2. A가 먼저 승인 → version 4로 증가
  3. B가 승인 시도
    • WHERE version = 3 조건 불일치
    • update 실패 → 충돌 감지

👉 DB가 최종 승자를 결정


6. update_dt로 대체하면 안 되는 이유 (요약)

  • 시간 정밀도 문제
  • 단조 증가 보장 없음
  • 의미가 다름
컬럼역할
version 동시성 제어
update_dt 이력/감사

7. STEP으로 낙관적 락을 구현할 수 있는가?

결론부터

예외적으로 가능하지만, 완전한 대체는 아니다.


STEP으로 가능한 경우 (아주 제한적)

다음 조건을 모두 만족해야 한다.

  • 단계가 단방향
  • 절대 되돌아가지 않음
  • 단계 수 고정
  • 단일 테이블
  • 단계 외 데이터 수정 없음
 
UPDATE loan SET step = 'APPROVED' WHERE id = 1 AND step = 'REVIEW';

이 경우:

  • 사실상 version과 같은 패턴
  • “부분적인 낙관적 락”이라고 볼 수 있음

8. STEP 기반 접근의 한계 (치명적)

1️⃣ STEP은 업무 의미다

  • 기획이 바꿈
  • 정책 변경 대상
  • 불변이 아님

동시성 제어와 성격이 다르다.


2️⃣ STEP은 되돌아갈 수 있다

  • 승인 취소
  • 재심사
  • 반려 후 재접수

이 순간 낙관적 락 전제가 깨진다.


3️⃣ 모든 변경을 감지하지 못한다

  • 금액 수정
  • 메모 수정
  • 옵션 변경

STEP이 안 바뀌면 충돌을 못 잡는다.


4️⃣ 로직이 더러워진다

 
if (step != REVIEW) { throw new BusinessException(); }
  • 동시성 제어가
  • 서비스 로직에 퍼짐
  • DB가 해야 할 일을 코드가 대신함

9. 실무 권장 구조

목적방법
동시성 제어 version
업무 흐름 step
이력/감사 update_dt

역할을 분리해야 안전하다.


10. 최종 결론

  • 낙관적 락은 version 기반 조건 업데이트
  • 비관적 락은 DB 락 선점
  • STEP으로 낙관적 락을 “흉내” 낼 수는 있지만
    • 범위 제한적
    • 정책 변경에 취약
    • 장기적으로 위험

STEP은 흐름이고,
VERSION은 안전장치다.

흐름으로 안전을 보장하려 하면 반드시 사고 난다.

 
반응형

댓글