[CS] 비관적 락(Pessimistic Lock)

khj·2025년 3월 26일

Computer Science

목록 보기
22/26
post-thumbnail

1. 비관적 락(Pessimistic Lock)란?

비관적 락은 데이터에 대한 잠금을 미리 설정하여 다른 트랜잭션이 해당 데이터를 수정하지 못하도록 막는 방식이다.
즉, 데이터에 대한 접근을 부정적으로 예상하고, 잠금을 걸어놓은 후 다른 트랜잭션들이 해당 데이터에 접근할 수 없게 만든다.


"다른 트랜잭션이 이 데이터를 변경할 가능성이 있으니 미리 잠그겠다"는 방식이다.

2. 비관적 락의 동작 원리

비관적 락은 트랜잭션이 데이터에 접근할 때마다 해당 데이터를 잠그는 방식으로 동작한다.
이 방식은 기본적으로 '데이터가 변경될 때마다 잠금'을 걸어놓고, 트랜잭션이 완료될 때까지 다른 트랜잭션들이 접근할 수 없게 만든다.

2.1. SQL에서 비관적 락 사용하기

비관적 락을 구현할 때는 SELECT FOR UPDATE 문을 사용한다.
이 문은 해당 데이터를 잠그고, 다른 트랜잭션이 데이터를 변경할 수 없도록 한다.

BEGIN;

SELECT * FROM account WHERE id = 1 FOR UPDATE;

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

COMMIT;
  • SELECT FOR UPDATE: 선택한 행에 대해 락을 걸어, 다른 트랜잭션에서 이 데이터를 수정할 수 없도록 한다.
  • 이 과정에서 다른 트랜잭션은 해당 데이터에 접근할 수 없으며, 트랜잭션이 끝나야 락이 풀린다.

3. 비관적 락의 유형

비관적 락은 크게 두 가지 유형으로 나눌 수 있다.

3.1. 공유 잠금 (Shared Lock)

  • 공유 잠금(Shared Lock)은 여러 트랜잭션이 동시에 데이터를 읽을 수 있도록 허용하지만, 수정은 불가능하게 한다.
  • 예를 들어, 여러 트랜잭션이 동일 데이터를 읽을 수 있지만, 데이터의 변경은 하나의 트랜잭션만 가능하다.

3.2. 배타 잠금 (Exclusive Lock)

  • 배타 잠금(Exclusive Lock)은 한 트랜잭션만 해당 데이터를 읽고 수정할 수 있도록 한다.
  • 다른 트랜잭션은 데이터를 읽고 수정할 수 없으며, 락이 해제될 때까지 기다려야 한다.

4. 비관적 락을 사용하는 이유

비관적 락은 데이터가 다른 트랜잭션에 의해 변경될 가능성이 높거나, 동시성 문제가 심각할 경우 유용하다.
이 방식은 경쟁 상태나 데이터 충돌을 막는 데 효과적이다.

비관적 락을 사용하는 경우

4.1. 동시성 문제 해결

예를 들어, 잔액을 차감하는 트랜잭션이 있을 때, 두 트랜잭션이 동시에 실행되면 잔액을 중복으로 차감하는 상황이 발생할 수 있다. 비관적 락을 사용하면 이런 문제를 방지할 수 있다.

4.2. 데이터 무결성 보장

재고 관리 시스템 등에서, 동시에 여러 트랜잭션이 하나의 상품을 구매하려고 할 때, 재고가 0인 상태로 여러 사람이 구매를 시도할 수 있는 상황을 방지할 수 있다.


5. 비관적 락의 장단점

장점

  • 동시성 문제 해결
    • 여러 트랜잭션이 동일 데이터를 수정하려 할 때, 경쟁 상태를 방지하고 데이터 충돌을 예방할 수 있다.
  • 데이터 무결성 유지
    • 트랜잭션이 끝날 때까지 데이터에 대한 접근을 차단함으로써, 데이터 무결성을 보장한다.

단점

  • 성능 저하

    • 비관적 락은 데이터베이스가 데이터를 잠그는 시간이 길어질수록 다른 트랜잭션들이 대기해야 하기 때문에 성능이 저하될 수 있다.
  • 교착 상태(Deadlock)

    • 두 개 이상의 트랜잭션이 서로 상대방이 잠근 리소스를 기다리며 교착 상태(Deadlock)가 발생할 수 있다. 이런 상황에서는 트랜잭션을 강제로 롤백하고 다시 시도해야 한다.
  • 스케일링 문제

    • 락이 걸린 데이터는 다른 트랜잭션이 접근하지 못하므로, 동시 접속자가 많은 시스템에서는 락 경합이 발생할 수 있다.

6. 비관적 락의 대안 - 낙관적 락(Optimistic Lock)

비관적 락은 트랜잭션이 데이터에 접근할 때마다 잠금을 걸기 때문에 성능 저하나 교착 상태 등의 문제가 발생할 수 있다.
이를 해결하기 위해 낙관적 락(Optimistic Lock)이 사용될 수 있다.
낙관적 락은 데이터를 수정할 때만 충돌이 발생한다고 가정하고, 수정 전후에 충돌 여부를 체크하는 방식이다.

낙관적 락은 성능이 중요한 경우에 유리하지만, 충돌 발생 시 별도의 처리 로직이 필요하다.

profile
Spring, Django 개발 블로그

0개의 댓글