[DB] DB Lock이란?

sinryuji·2025년 4월 1일

1. DB Lock이란?

DB 락(Database Lock)은 데이터베이스에서 여러 트랜잭션이 동시에 같은 데이터에 접근할 때, 데이터의 무결성(일관성)을 보장하기 위해 사용되는 메커니즘입니다.

쉽게 말해, 한 트랜잭션이 특정 데이터에 대해 작업을 하고 있을 때 다른 트랜잭션이 그 데이터에 접근하지 못하도록 잠그는 것입니다. 이로써 데이터의 일관성을 유지하고, 동시에 발생할 수 있는 충돌을 방지할 수 있습니다.

2. DB Lock의 필요성

데이터베이스는 여러 사용자나 시스템이 동시에 데이터를 읽고 쓰는 환경에서 운영됩니다. 이런 환경에서 다음과 같은 문제들이 발생할 수 있습니다.

2.1 Dirty Read (더티 리트)

한 트랜잭션이 데이터를 수정 중일 때 다른 트랜잭션이 그 데이터를 읽는 문제입니다. 만약 첫 번째 트랜잭션이 롤백된다면, 두 번째 트랜잭션은 잘못된 데이터를 읽은 것이 됩니다.

  1. 트랜잭션 A가 고객의 은행 계좌 잔액을 수정하고 1000원을 더합니다. 잔액이 5000원에서 6000원으로 변경됩니다. 하지만 트랜잭션 A는 아직 이 변경을 커밋하지 않았습니다.
  2. 트랜잭션 B가 같은 고객의 계좌 잔액을 조회하여 6000원이라고 읽습니다. 트랜잭션 B는 이 잔액을 기반으로 다른 계산을 수행합니다.
  3. 트랜잭션 A가 예기치 않은 오류로 인해 롤백되어, 잔액은 다시 5000원으로 되돌아갑니다.
  4. 그러나 트랜잭션 B는 이미 잘못된 6000원을 읽었으므로, 이로 인해 부정확한 계산이 발생할 수 있습니다.

2.2 Non-repeatable Read (반복 불가능한 읽기)

한 트랜잭션이 데이터를 읽은 후, 다른 트랜잭션이 그 데이터를 수정하고 커밋하여 첫 번째 트랜잭션이 동일한 데이터를 다시 읽을 수 없는 문제입니다.

  1. 트랜잭션 A가 고객의 계좌 잔액을 읽습니다. 이때 계좌 잔액은 5000원입니다.
  2. 트랜잭션 B가 같은 고객의 계좌 잔액을 7000원으로 수정하고 커밋합니다.
  3. 트랜잭션 A가 동일한 고객의 계좌 잔액을 다시 읽습니다. 이번에는 잔액이 7000원으로 표시됩니다.
  4. 트랜잭션 A는 같은 트랜잭션 내에서 동일한 데이터를 두 번 읽었지만, 그 값이 일관되지 않게 변경된 것을 확인합니다.

2.3 Lost Update (업데이트 손실)

두 개의 트랜잭션이 동시에 같은 데이터를 수정하려고 할 때, 한 트랜잭션의 수정 내용이 다른 트랜잭션에 의해 덮어쓰여져 사라지는 문제입니다.

  1. 트랜잭션 A가 고객의 계좌 잔액을 5000원에서 6000원으로 수정합니다. 하지만 아직 커밋하지 않았습니다.
  2. 트랜잭션 B도 같은 고객의 계좌 잔액을 5000원에서 7000원으로 수정하고, 즉시 커밋합니다.
  3. 트랜잭션 A가 자신의 변경 사항을 커밋합니다.
  4. 결과적으로 계좌 잔액은 6000원으로 저장됩니다. 그러나 트랜잭션 B가 먼저 커밋한 7000원으로의 변경은 사라져 버렸습니다. 이 상황을 업데이트 손실이라고 합니다.

위와 같은 문제들을 예방하기 위해 DB Lock을 통해 데이터에 대한 접근을 제어할 필요가 있습니다.

3. DB Lock의 종류

락의 종류는 크게 다음과 같이 2가지 종류로 나뉩니다.

3.1 공유 락 (Shared Lock, S Lock)

공유 락은 데이터베이스에서 데이터를 읽을 때 사용됩니다. 여러 트랜잭션이 동시에 같은 데이터를 읽을 수 있지만, 공유 락이 걸린 동안에는 데이터를 수정할 수 없습니다.

  • 상황: 고객 정보 시스템에서 여러 직원이 동시에 같은 고객의 정보를 조회할 수 있지만, 조회 중에는 그 정보를 수정할 수 없습니다.
  • 예시:
    • 트랜잭션 A가 고객 A의 정보를 조회합니다. 이때 고객 A의 정보에 대해 공유 락이 걸립니다.
    • 트랜잭션 B도 동시에 고객 A의 정보를 조회합니다. 공유 락이 이미 걸려 있으므로, 트랜잭션 B는 정상적으로 고객 정보를 읽을 수 있습니다.
    • 트랜잭션 C가 고객 A의 정보를 수정하려고 시도합니다. 하지만 공유 락 때문에 수정 작업이 차단되거나 대기 상태가 됩니다.
    • 트랜잭션 A와 B가 조회를 끝내고 공유 락이 해제된 후에야 트랜잭션 C가 고객 정보를 수정할 수 있습니다.

3.2 배타 락 (Exclusive Lock, X Lock)

배타 락은 데이터를 수정할 때 사용됩니다. 배타 락이 걸린 데이터는 다른 트랜잭션이 읽거나 수정할 수 없습니다. 한 트랜잭션이 배타 락을 획득하면 다른 모든 트랜잭션은 해당 데이터에 접근할 수 없습니다.

  • 상황: 재고 관리 시스템에서 한 직원이 특정 상품의 재고를 수정하고 있을 때, 다른 직원이 그 상품의 재고를 조회하거나 수정하지 못하게 하는 상황.
  • 예시:
    • 트랜잭션 A가 상품 A의 재고를 100에서 150으로 수정하려고 합니다. 이때 상품 A에 대해 배타 락이 걸립니다.
    • 트랜잭션 B가 상품 A의 재고를 조회하려고 하지만, 배타 락 때문에 대기 상태가 됩니다.
    • 트랜잭션 C가 상품 A의 재고를 150에서 200으로 수정하려고 하지만, 마찬가지로 대기 상태가 됩니다.
    • 트랜잭션 A가 재고 수정 작업을 완료하고 커밋한 후, 락이 해제되면 트랜잭션 B와 C가 차례로 진행될 수 있습니다.

4. 블로킹 (Blocking)

블로킹은 Lock 간의 경합이 발생해서 특정 트랜잭션이 작업을 진행하지 못하고 대기하는 상태를 의미합니다.

  • 특정 데이터에 공유 Lock이 설정된 상태에서 다른 트랜잭션이 해당 데이터에 배타 Lock을 설정하려고 할 때
  • 특정 데이터에 배타 Lock이 설정된 상태에서 다른 트랜잭션이 해당 데이터에 공유 Lock을 설정하려고 할 때

출처: https://ksh-coding.tistory.com/121#1.%20%EB%9D%BD%EC%9D%98%20%EC%A2%85%EB%A5%98-1

블로킹의 해결 방안은 다음과 같습니다.

  1. 트랜잭션 작업 단위를 최대한 적게 구성하기
    • 트랜잭션의 작업 단위를 적게 구성하면 그만큼 빠르게 트랜잭션이 종료되기 때문에 블로킹 상태 해결이 빠를 것입니다.
    • JPA 사용 시 생명 주기가 다른 객체간의 직접 참조를 간접 참조로 끊는 방법도 트랜잭션 작업 단위를 적게 구성하여 블로킹 상태를 빠르게 해결하는 예시가 될 수 있습니다.
  2. 동일한 데이터를 동시에 변경하는 작업을 하지 않도록 설계하기
    • 불가피하게 동시에 변경하는 작업이 존재할 경우 동시성을 해결하는 비관적 락, 낙관적 락을 사용하여 해결할 수 있습니다.

5. 데드락 (Dead Lock)

데드락은 두 트랜잭션 모두 블로킹 상태에 진입하여 서로의 블로킹을 해결할 수 없는 상태입니다.

트랜잭션 A, B에서 A가 B의 트랜잭션에 대해 블로킹 상태로 진입한 경우에 B 트랜잭션이 종료(커밋 or 롤백) 되기까지 A 트랜잭션이 대기 상태에 들어갑니다. 해당 상황에서 동시에 B 트랜잭션이 A에 대해 블로킹 상태로 진입한다면 B 트랜잭션 역시 A 트랜잭션이 종료 되기까지 대기 상태에 들어가기 때문에 서로의 블로킹을 영원히 해결할 수 없는 상태가 됩니다. 이런 상태를 데드락 (Dead Lock)이라고 합니다.


출처: https://ksh-coding.tistory.com/121#1.%20%EB%9D%BD%EC%9D%98%20%EC%A2%85%EB%A5%98-1

  1. 세션 A에서 Coupon 데이터에 X-Lock 설정 & 세션 B에서 Member 데이터에 X-Lock 설정
  2. 세션 A에서 X-Lock 설정이 되어있는 Member 데이터에 S-Lock을 설정
  3. Member 데이터에는 이미 X-Lock 설정이 되어 있으므로 트랜잭션 A는 블로킹 상태 진입
  4. 세션 B에서도 X-Lock 설정이 되어 있는 Coupon 데이터에 S-Lock 설정
  5. Coupon 데이터에는 이미 X-Lock 설정이 되어 있으므로 트랜잭션 B는 블로킹 상태 진입
  6. 트랜잭션 A, B의 블로킹 상태는 상대 트랜잭션이 종료되어야 해결되는데 서로의 트랜잭션이 블로킹 상태이기 때문에 종료되지 않으므로 데드락 상태가 됩니다.

데이터베이스에서는 기본적으로 데드락 감지 기능이 있습니다. 그래서 데드락이 감지되면 해당 트랜잭션을 롤백하여 데드락 상태에 빠지지 않게 합니다. 하지만 이 기능을 끌 경우 Lock Timeout 시간이 지날 때 까지 데드락 상태에 빠지게 됩니다.

참고

https://ksh-coding.tistory.com/121#1.%20%EB%9D%BD%EC%9D%98%20%EC%A2%85%EB%A5%98-1

profile
응애 개발자입니다.

0개의 댓글