오늘의 인기 글
최근 글
최근 댓글
Today
Total
04-28 00:01
관리 메뉴

우노

[DB] Optimistic Lock(낙관적 락), Pessimistic Lock(비관적 락), Distributed Lock(분산 락)이란? 본문

Database/Concept

[DB] Optimistic Lock(낙관적 락), Pessimistic Lock(비관적 락), Distributed Lock(분산 락)이란?

운호(Noah) 2024. 3. 18. 18:23

들어가기 앞서,

  • DB 데이터를 수정할 때, 여러 트랜잭션이 동시에 동일한 데이터에 접근하여 충돌이 발생할 수 있습니다.
  • 이러한 상황에서 데이터 무결성을 유지하기 위해서는 적절한 잠금(Locking) 기법을 사용해야 합니다.
  • 해당 포스팅에서는 Optimistic Lock(낙관적 락), Pessimistic Lock(비관적 락), Distributed Lock(분산 락)에 대해서 살펴보겠습니다.

Optimistic Lock(낙관적 락)이란?

  • 설명
    • 데이터 수정 시, 다른 트랜잭션에 의해 데이터가 변경되지 않았는지 확인하는 방식입니다.
  • 특징
    • 동시성이 높고 충돌 가능성이 낮은 경우 효율적입니다.
      • 충돌 시, 작업을 재시작해야 하므로 낭비가 발생할 수 있습니다.
      • 개발자가 수동으로 롤백처리를 한땀한땀 해줘야합니다.
    • 데이터 일관성이 완벽하게 보장되지 않습니다.
  • 사용 예제
    • SNS 좋아요 기능
      • 데이터 정확성에 대한 요구사항이 높지 않습니다. (충돌이 발생하더라도 사용자가 다시 좋아요를 누르면 됩니다.)
      • 약간의 지연은 허용 가능합니다.

Optimistic Lock(낙관적 락) 동작 방식

  • 진행 순서
    • 트랜잭션1이 계좌 테이블의 Id 1번을 읽음 ( id = 1 , 잔고 = 10,000 , version = 1 )
    • 트랜잭션2가 계좌 테이블의 Id 1번을 읽음 ( id = 1 , 잔고 = 10,000 , version = 1 )
    • 트랜잭션2가 Id 1번, version 1인 row의 잔고 갱신 ( id = 1 , 잔고 = 15,000 , version = 2 ) 성공
    • 트랜잭션1이 Id 1번, version 1인 row의 잔고 갱신 ( id = 1 , 잔고 = 2,000 , version = 2 ) 실패
      • Id 1번의 version은 2로 업데이트 되었기 때문에 트랜잭션1은 해당 row를 갱신하지 못함
  • 즉, 같은 레코드에 대해 트랜잭션1과 트랜잭션2의 수정 요청이 있었지만,
  • 트랜잭션2가 먼저 업데이트되면서 version이 변경되었기 때문에 나중에 시도한 트랜잭션1의 수정 요청은 반영되지 않았습니다.
  • 낙관적 락은 version과 같은 별도의 컬럼을 두어 충돌하는 업데이트를 방지합니다.
  • 레코드를 읽을 때 version 값도 함께 읽고, 업데이트 시에는 기존 version 값을 조건으로 추가하여 동시 수정 충돌을 검출합니다.
  • version 컬럼 외에도 hashcode나 timestamp를 사용하기도 합니다.

Pessimistic Lock(비관적 락)이란?

  • 설명
    • 트랜잭션이 데이터를 읽거나 수정하기 전에, 해당 데이터에 대한 잠금(Lock)을 획득하는 방식입니다.
  • 특징
    • 동시성이 낮고 데이터 무결성을 철저히 보장해야 하는 경우 효율적입니다.
      • 한 트랜잭션이 데이터에 락을 획득하면 다른 트랜잭션은 그 데이터에 접근할 수 없어 동시 수정 문제가 발생하지 않습니다.
    • 락을 너무 오래 유지하면 병목 현상이 발생할 수 있습니다.
  • 사용 예제
    • 은행 계좌 이체, 항공권 예매 등
      • 데이터 정합성이 중요하고 동시 액세스 비율이 높지 않습니다.
      • 동시 수정으로 인한 데이터 무결성 문제가 발생하면 안 됩니다.

Pessimistic Lock(비관적 락) 동작 방식

  • 진행 순서
    1. 트랜잭션1이 Id가 1인 row에 대해 락을 요청하고 획득함
    2. 트랜잭션1이 Id가 1인 row를 읽음
    3. 트랜잭션2가 Id가 1인 row에 대해 락을 요청하지만, 트랜잭션1이 락을 보유하고 있기 때문에 대기 상태로 들어감
    4. 트랜잭션1이 Id가 1인 row의 잔고값을 갱신함
    5. 트랜잭션1이 갱신 작업을 완료하고, 락을 해제함
    6. 트랜잭션2가 이제 락을 획득하고, Id가 1인 row를 읽음
    7. 트랜잭션2가 Id가 1인 row의 잔고값을 갱신함
  • 이렇게 각각의 트랜잭션이 데이터에 대한 독점적인 접근을 보장받아, 충돌이나 데이터의 일관성 문제 없이 안전하게 데이터를 갱신할 수 있습니다.

Distributed Lock(분산 락)이란?

  • 설명
    • 여러 작업(공유 자원에 접근하는 트랜잭션)들이 순차적으로 진행되어야할 때,
    • 전체 작업의 동시성과 데이터의 일관성을 유지하기 위해 사용됩니다.
  • 특징
    • 장점
      • 데이터 일관성 보장 : 분산 시스템에서 여러 트랜잭션/프로세스가 동일 자원에 접근할 때 데이터 무결성과 일관성 유지
      • 동시성 제어 : 동시 실행 시 발생 가능한 충돌이나 데이터 경쟁 조건 방지
    • 단점
      • Lock 타임아웃 부재 : 설정된 타임아웃 없이 락 획득 실패 시 무한 대기 상태로 인한 응답성 저하 위험
      • 자원 효율성 저하 : 락을 오랫동안 유지해야 할 경우 다른 프로세스/트랜잭션 작업 지연 발생 가능
  • 사용 예제
    • "주문 처리", "재고 관리", "결제 처리"와 같은 연관된 쿼리가 순서대로 실행되어야 하는 상황에서,
    • 각 쿼리가 별도의 트랜잭션으로 처리되어 트랜잭션 간 순서가 보장되지 않는 경우.
    • 분산 락을 사용하여 전체 작업 전에 락을 획득하고, 작업이 완료된 후 락을 해제함으로써 트랜잭션들 사이의 실행 순서를 보장할 수 있습니다.

참고

Comments