낙관적 락과 비관적 락

2026.01.13. 11:24

“낙관적 락”과 “비관적 락”은 동시에 여러 작업(트랜잭션/스레드)이 같은 데이터를 건드릴 때 충돌을 어떻게 다룰지에 대한 방식이에요.

(DB 트랜잭션, 분산 시스템, JPA/Hibernate 등에서 자주 나옵니다.)


1) 낙관적 락 (Optimistic Lock)

핵심 아이디어

  • 충돌이 “자주 일어나지 않는다”고 가정

  • 미리 잠그지 않고 그냥 읽고/수정 시도

  • 커밋할 때 버전(version) 비교로 충돌 여부 체크

동작 방식

  1. A와 B가 같은 데이터를 읽음

  2. A가 수정 후 저장(버전 1→2)

  3. B가 수정 후 저장하려고 하면,

    • B가 읽었던 버전은 1인데 지금 DB는 2라서 → 충돌 발생

    • 저장 실패(예외) → 재시도/롤백/사용자에게 알림

장점

  • 락을 오래 잡지 않아서 성능 좋고 병렬성 높음

  • 읽기 많은 시스템에 유리

단점

  • 충돌 나면 다시 시도해야 해서 충돌이 잦으면 오히려 비용 증가

대표 구현

  • 버전 컬럼(version, timestamp) 기반

  • JPA의 @Version


2) 비관적 락 (Pessimistic Lock)

핵심 아이디어

  • 충돌이 “자주 일어난다”고 가정

  • 데이터를 수정할 가능성이 있으면 처음부터 잠금

  • 다른 작업은 락이 풀릴 때까지 대기/실패

동작 방식

  1. A가 데이터를 읽으면서 락 획득

  2. B가 같은 데이터 수정하려고 하면

    • A가 끝날 때까지 대기(block) 또는 타임아웃/실패

  3. A 트랜잭션 종료 → 락 해제 → B 진행

장점

  • 충돌 자체를 막아서 데이터 정합성 확보가 확실

  • “무조건 성공해야 하는 처리”(재고 차감 등)에 적합

단점

  • 락 때문에 대기 발생 → 성능 저하

  • 데드락 위험

대표 구현

  • SELECT ... FOR UPDATE

  • JPA의 LockModeType.PESSIMISTIC_WRITE


한 줄 비교 요약

  • 낙관적 락: 일단 해보고, 마지막에 버전 체크로 충돌 처리

  • 비관적 락: 처음부터 잠그고, 다른 접근을 막아서 충돌 방지


어떤 걸 써야 해?

  • 읽기 많고 충돌이 드문 서비스 → ✅ 낙관적 락 (대부분의 일반 서비스)

  • 충돌이 잦거나, 반드시 순서 보장/정합성이 중요한 처리(재고/좌석/쿠폰) → ✅ 비관적 락

원하면 “재고 차감” 같은 예시로 실제 SQL/JPA 코드까지 같이 보여줄게요.