
비관적 락은 데이터에 대한 잠금을 미리 설정하여 다른 트랜잭션이 해당 데이터를 수정하지 못하도록 막는 방식이다.
즉, 데이터에 대한 접근을 부정적으로 예상하고, 잠금을 걸어놓은 후 다른 트랜잭션들이 해당 데이터에 접근할 수 없게 만든다.
"다른 트랜잭션이 이 데이터를 변경할 가능성이 있으니 미리 잠그겠다"는 방식이다.
비관적 락은 트랜잭션이 데이터에 접근할 때마다 해당 데이터를 잠그는 방식으로 동작한다.
이 방식은 기본적으로 '데이터가 변경될 때마다 잠금'을 걸어놓고, 트랜잭션이 완료될 때까지 다른 트랜잭션들이 접근할 수 없게 만든다.
비관적 락을 구현할 때는 SELECT FOR UPDATE 문을 사용한다.
이 문은 해당 데이터를 잠그고, 다른 트랜잭션이 데이터를 변경할 수 없도록 한다.
BEGIN;
SELECT * FROM account WHERE id = 1 FOR UPDATE;
UPDATE account SET balance = balance - 100 WHERE id = 1;
COMMIT;
비관적 락은 크게 두 가지 유형으로 나눌 수 있다.
비관적 락은 데이터가 다른 트랜잭션에 의해 변경될 가능성이 높거나, 동시성 문제가 심각할 경우 유용하다.
이 방식은 경쟁 상태나 데이터 충돌을 막는 데 효과적이다.
예를 들어, 잔액을 차감하는 트랜잭션이 있을 때, 두 트랜잭션이 동시에 실행되면 잔액을 중복으로 차감하는 상황이 발생할 수 있다. 비관적 락을 사용하면 이런 문제를 방지할 수 있다.
재고 관리 시스템 등에서, 동시에 여러 트랜잭션이 하나의 상품을 구매하려고 할 때, 재고가 0인 상태로 여러 사람이 구매를 시도할 수 있는 상황을 방지할 수 있다.
성능 저하
교착 상태(Deadlock)
스케일링 문제
비관적 락은 트랜잭션이 데이터에 접근할 때마다 잠금을 걸기 때문에 성능 저하나 교착 상태 등의 문제가 발생할 수 있다.
이를 해결하기 위해 낙관적 락(Optimistic Lock)이 사용될 수 있다.
낙관적 락은 데이터를 수정할 때만 충돌이 발생한다고 가정하고, 수정 전후에 충돌 여부를 체크하는 방식이다.
낙관적 락은 성능이 중요한 경우에 유리하지만, 충돌 발생 시 별도의 처리 로직이 필요하다.