본문 바로가기
동시성 제어

동시성 제어 3가지 방식 정리 (낙관적 락 / 비관적 락 / 원자적 UPDATE)

by 옹알이옹 2026. 2. 25.
목차

1. 낙관적 락

2. 비관적 락(명시적 락)

3. 원자적 UPDATE

 

 

 

1. 낙관적 락

 

1) 개념

  • 데이터에 version 컬럼을 두고 UPDATE 하기 조회 당시 version과 실제 update 시 version이 같아야 업데이트 성공
  • 경쟁을 막지 않고 허용하되 커밋 시점에 충돌을 감지하여 실패 처리한다.
  • ⇒ A,B,C가 거의 동시에 접근한다면 A만 성공 B,C는 바로 예외 터짐
  • 동시 접근 자체가 예외를 발생시키기 때문에 그에 대한 재시도or실패 처리가 꼭 필요하다.

2) 낙관적 락이 적합한 상황

충돌이 드물고 만약 발생하더라도 실패 후 다시 시도하는 비용이 크지 않은 경우에 적합함.

예시 상황

  • 게시물의 제목이나 내용 등을 수정하는 경우
  • 관리자 화면에서 간헐적으로 수정되는 값

이런 상황에서는 여러 사용자가 동시에 같은 row를 수정할 가능성이 낮고 재시도 비용이 낮다

⇒ 결론적으로 대부분의 요청이 충돌 없이 성공하고 드물게 충돌하면 실패/재시도가 자연스러운 경우에 적합

 

3) 낙관적 락이 부적합한 상황

 

 1. 정원/재고/좌석 같은 카운터 증가 구조

예를 들어 정원 50명인 스터디에 40명이 동시에 가입을 시도한다고 가정한다.

낙관적 락을 사용하면 다음과 같은 일이 벌어짐.

  • 40명이 동시에 같은 version을 읽는다.
  • 1명만 UPDATE 성공한다.
  • 나머지 39명은 전부 실패한다.

이때 후처리 방식에 따라 각각 문제가 발생한다.

 

case 1. 재시도 처리

  •  실패한 39명의 재시도 처리 자체가 다시 충돌을 일으킬 수 있음. 최대 39번 반복이 아닌 그 이상으로 반복하여 트래픽의 폭발 가능

case 2. 바로 종료 처리

  • 아직 자리가 남아 있어도 충돌로 실패하는 사용자가 발생.
  • 사용자 입장에선 가입 신청이 실패한 이유가 모호하다.(서버에서 다른 누군가 동시에 신청했다고 예외가 터졌으니)
  • 성공 여부가 타이밍에 따라 운으로 결정된다.

 2. 이벤트성 처리 로직

  • 한정 쿠폰 100장
  • 콘서트 좌석
  • 한정 특가 상품

이런 경우 충돌이 예외적으로 드문 상황이 아니라 충돌이 보편적인 상황이 된다.

위와 같은 이유로 이런 경우도 낙관적락을 사용하면 안 된다.

 

 2. 비관적 락(명시적 락)

 

1) 개념

  • 경쟁이 발생할 수 있는 row를 select for update 등으로 먼저 잠그고 그 잠금이 해제될 때까지 다른 트랜잭션의 접근을 대기시키는 방식이다.
  • 충돌 자체를 못 일으키게 줄을 세우는 방식
  • 낙관적락은 5명이 동시에 접근하면 4명은 실패하지만 해당 처리는 5명 모두 성공 가능

2) 비관적 락이 적합한 상황

 

자원에 대한 경쟁이 잦고 여러 Row를 동시에 검증 & 수정해야 하는 경우

 

예시 상황

  • 계좌 이체: A 계좌 차감, B계좌 증감
  • 여러 상품을 동시에 검증 후 차감해야 하는 주문

=> 위의 케이스와 같이 여러 row에 대한 검증 및 수정 시점에 정합성이 보장받아야 할 경우에 적합하며 
     단일 row에 대한 검증과 수정이 가능하다면 대부분 원자적 update가 유리함

3) 비관적 락 사용 시 주의점

  • 락 구간을 최대한 짧게 잡는다.
    • 잠그고 기다리는 비용이 있으니 락 잡고 외부 호출(메일/결제 API) 같은 오래 걸리는 작업이 끼면 병목 현상이 발생한다.
      (select for update로 잡금 조회를 호출하는 메서드에서 외부 API 등을 호출하지 않는다)
  • 타임아웃 정책을 명확히 설정해야 한다
    • 비관적 락은 대기를 하는 동작이기 때문에 TIME OUT 설정 및 처리가 필수
  • DEAD LOCK에 대한 예외 처리/재시도 전략이 있어야 한다.
  • DB 격리 수준에 따라 잠금 범위가 달라질 수 있다.
    • READ COMMITTED ⇒ 해당 row만 잠금
    • REPEATABLE READ ⇒ 경우에 따라 범위로 잡혀 여러 row 가 잠길 수 있음

 3. 원자적 UPDATE

 

1) 개념

  • UPDATE 문 자체에 조건을 포함시켜 조건이 만족하는 경우에만 변경이 일어나도록 하는 방식
  • 읽기-검증-쓰기 과정을 분리하지 않고 쓰기 시점에 한 번에 검증 + 수정을 수행한다
  • 충돌을 대기로 흡수하지 않고 조건 불일치 시 0 row update로 즉시 실패시킨다
  • 조건 만족 -> update 결과 1 -> 성공
  • 조건 불만족 -> update 결과 0 -> 실패 

코드 예시

UPDATE study_group
SET current_member_count= current_member_count+1 -- 조건 만족하면 현재원 증가
WHERE id= ?
AND current_member_count< capacity; -- 현재원이 정원보다 적어?

이와 같이 검증과 수정 자체를 하나의 쿼리에서 처리하여 읽기와 쓰기 사이에 간극이 있을 수 없다.

 

2) 원자적 UPDATE가 적합한 상황

경쟁은 정상이며 일부만 성공하면 되는 구조에 적합

  • 한정된 자원을 두고 일부만 성공시키고 나머진 실패 처리하는 경우
  • 실패가 비즈니스적으로 자연스러운 경우

예시 상황

  • 정원 제한 스터디 가입
  • 한정 쿠폰 100장 발급
  • 이벤트 경품 50개
  • 재고 감소 처리

3) 원자적 update가 부적합한 상황

 

복합 검증이 필요한 경우

  • 여러 row를 읽어 계산 후 판단해야 하는 경우
  • 집계/상태 조합/정책 판단이 복잡한 경우
  • 단일 UPDATE 조건으로 표현이 어려운 경우

⇒ 이런 복합 검증이 필요한 상황에선 명시적 락으로 처리