[DB] 비관적 락과 낙관적 락

2026. 5. 1. 20:23·Backend/DB

  동시성 제어를 위해서 DB에서는 Lock을 사용합니다. 여러 사용자가 동시에 같은 데이터를 수정하려고 할 때 데이터 충돌을 어떻게 처리할 것인가에 대해서 대표적인 방법으로 비관적 락과 낙관적 락이 있습니다.

비관적 락 (Pessimistic Lock)

  누군가 동시에 수정할 가능성이 높다고 비관적으로 가정하고 잠금 처리하는 방법입니다.

동작 방식

1. 데이터를 읽는 순간 배타적 락(Exclusive Lock)을 겁니다.

2. 해당 트랜잭션이 끝날 때까지 다른 트랜잭션은 해당 행을 수정할 수 없습니다.

3. 수정이 끝난 후에야 락이 해제됩니다.

비관적 락

장점

  • 충돌이 발생했을 때 즉시 감지 가능합니다.
  • 데이터 정합성을 강력하게 보장합니다.
  • 복잡한 로직에서 데이터가 안전합니다.

단점

  • 락 대기 시간이 길어지면 성능 저하가 발생합니다.
  • 데드락(Deadlock) 발생 가능성이 높습니다.
    • 락을 더 오래, 더 많은 자원에 걸기 때문에 점유 대기 시간이 더 길어지고, 락 획득 순서가 꼬일 가능성이 커지기 때문입니다.
  • 동시 처리량(Throughput)이 낮아집니다.

적합한 경우

  은행 계좌 이체, 재고 차감, 좌석 예약 등 충돌이 자주 발생하고, 절대 틀리면 안되는 작업에 적합합니다.

예시

SELECT * FROM account 
WHERE id = 100 
FOR UPDATE;        ← 여기서 락이 걸림

UPDATE account SET balance = balance - 50000 
WHERE id = 100;

 

낙관적 락 (Optimistic Lock)

  대부분은 충돌이 발생하지 않을테니 일단 수정하고 나중에 충돌이 발생했으면 그때 처리하는 방법입니다. 즉, 실제 수정 시점에만 충돌을 검사합니다.

동작 방식

1. 데이터에 버전 컬럼을 추가합니다.

2. 데이터를 읽을 때는 락을 걸지 않습니다.

3. 수정할 때, 읽었을 때의 버전과 현재 버전이 같은지 확인합니다.

4. 같으면 수정하고 버전을 증가시킵니다.

5. 다르면 충돌로 간주하고 롤백 또는 재시도합니다.

낙관적 락

 

장점

  • 락을 거의 걸지 않게돼서 동시성이 매우 높습니다.
  • 대기 시간이 거의 없습니다.
  • 읽기 위주의 작업에 매우 유리합니다.

단점

  • 충돌이 자주 발생하게 되면 재시도 로직이 복잡해집니다.
  • 충돌률이 높으면 오히려 성능이 더 떨어질 수 있습니다.

적합한 경우

  게시판, 사용자 프로필 수정 등 충돌이 드문 일반적인 웹 서비스 또는 읽기 작업이 압도적으로 많은 시스템

예시

-- 데이터를 읽음 (락 없음)
SELECT stock, version FROM product WHERE id = 5;   -- stock=100, version=7

-- 수정 시 버전까지 함께 체크
UPDATE product 
SET stock = stock - 1, 
    version = version + 1
WHERE id = 5 
  AND version = 7;     ← 여기서 충돌 체크

 

❓일반적인 웹 서비스에서는 비관적 락이 적합한데, 왜 버전 컬럼 추가 등의 예상되는 작업이 필요한가?

더보기

  낙관적 락이 더 편하고 성능도 좋은데, 왜 기본으로 안 쓰이고 버전 컬럼을 일부러 추가해야하지? 하고 의문이 들수 있습니다.

 

  대부분의 RDBMS는 기본적으로 비관적 락 스타일의 동시성 제어를 사용하도록 설계돼있기 때문입니다.

 

  이는 최초에 설계될 때 ACID 보장을 더 중요시 했기 때문인데, 당시 웹 트래픽 규모와 충돌 빈도가 지금과 달랐기 때문에 문제가 되지 않았습니다.

 

  또한 낙관적 락은 충돌 감지와 재시도 로직을 애플리케이션 개발자가 책임져야 하기 때문에 DB 입장에서는 개발자가 실수하면 데이터가 깨질 위험성이 존재하는 상황을 일반화시키면 안 됩니다. 낙관적 락이 기본 값이 된다고 해도 모든 테이블에 버전 컬럼을 강제로 추가하면 읽기 전용 테이블, 로그 테이블, 이력 테이블 등에서는 완전히 불필요한 오버헤드가 됩니다. 따라서 낙관적 락을 사용하고 싶으면 개발자가 직접 버전 컬럼을 추가하고 충돌 처리 로직을 구현해야 합니다.

 

*MySQL, Oracle 등의 전통적인 DBMS는 비관적 락 성향이 강하지만, PostgreSQL의 경우 MVCC가 매우 강력해서 락을 거의 걸지 않아 전통적인 RDBMS 보다는 덜 비관적입니다.

반응형

'Backend > DB' 카테고리의 다른 글

[DB] 데이터 모델링  (0) 2026.05.30
[MySQL] MySQL에서의 트랜잭션과 잠금 분석  (0) 2026.03.26
[MySQL] InnoDB 스토리지 엔진 아키텍처 분석  (0) 2026.03.16
[MySQL] MySQL 엔진 아키텍처 분석  (0) 2026.03.05
'Backend/DB' 카테고리의 다른 글
  • [DB] 데이터 모델링
  • [MySQL] MySQL에서의 트랜잭션과 잠금 분석
  • [MySQL] InnoDB 스토리지 엔진 아키텍처 분석
  • [MySQL] MySQL 엔진 아키텍처 분석
soberyl
soberyl
개발과 청춘 일지
    반응형
  • soberyl
    soberyl 님의 블로그
    soberyl
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 프로젝트
        • Snap Trade
        • 팀 프로젝트
        • 오픈 소스
      • 개발일지
        • 코딩 테스트
        • 알고리즘
        • CS
      • Full stack
      • Frontend
        • UXUI
        • React
        • Next.js
        • React Native
        • Monitor
      • Backend
        • NestJS
        • Spring
        • Monitor
        • DB
      • DevOps
        • CICD
      • Test
      • AI
      • Infra
        • AWS
        • On-premise
      • 청춘
        • 희곡
        • 연극
      • 잡설
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    DB
    io
    코딩테스트
    MySQL
    거래소
    프론트엔드
    java
    memory
    설계
    thread
    백엔드
    EC2
    알고리즘
    OS
    희곡
    CPU
    코테
    연극
    테스트
    최적화
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
soberyl
[DB] 비관적 락과 낙관적 락
상단으로

티스토리툴바