Search

비관적 락 vs 낙관적 락

생성일
2023/11/25 11:52
태그

비관적 락(Pessimistic Lock)

비관적 락은 트랜잭션이 시작될 때 Shared Lock(S Lock) 또는 Exclusive Lock을 걸어, 다른 트랜잭션에서 읽고 있는 데이터를 수정하는 것을 막는 동시성 제어 방법이다. 즉, 충돌이 발생할 것을 대비해 데이터에 락을 걸어 충돌을 예방하는 방식이다.
JPA에서는 LockModeType을 사용하여 비관적 락을 제공하고, 트랜잭션이 시작할 때 S Lock과 X Lock을 선택하여 잠글 수 있다.
비관적 락 방식에서 여러 트랜잭션이 데이터에 접근한다면, 우선적으로 Lock을 획득한 트랜잭션이 commit이나 rollback으로 Lock을 반납하는 것을 대기해야한다.

낙관적 락

낙관적 락은 잠금을 걸지 않고 데이터를 조회 및 수정을 시도하고, 조회 시점의 값과 수정 시점의 값이 서로 다르면 오류를 발생시켜 수정할 수 없도록 하는 방법이다. 즉, 충돌이 발생하지 않을 거라 가정하고 충돌이 발생한 경우에 대비하는 방식이다.
JPA에서는 Entity에 version을 저장해두고 값이 업데이트 될 때마다 version을 수정하는 versioning으로 낙관적 락을 제공한다. 조회 시점의 version과 수정 시점의 version이 다르면 충돌이 발생하여 오류를 띄운다.
낙관적 락 방식에서 충돌이 발생하면 개발자가 application level에서 직접 rollback이나 재시도를 시도하여 오류를 해결해야한다.

비교

비관적 락은 한 트랜잭션에서 특정 값을 읽거나 수정하고 있다면, 다른 트랜잭션에서는 Lock에 따라 대기해야 하는 상황이 발생할 수 있다. 다시 말해, 데이터 자체에 잠금을 걸기 때문에 동시성이 떨어져 성능이 많이 저하되고, 교착상태(Dead Lock)가 발생할 가능성이 있다.
반면 낙관적 락은 Lock을 걸지 않고 데이터를 조회, 수정하기 때문에 일반적으로 비관적 락 방식에 비해 성능이 더 좋다. 다만 개발자가 충돌 상황에 대한 처리를 직접 해주어야하고, 이러한 충돌이 빈번하게 발생하는 상황에서는 오히려 비관적 락에 비해 성능이 저하될 수 있다.
따라서 데이터의 무결성이 중요하고 충돌 상황이 자주 발생할 것으로 예상된다면 비관적 락을 사용하고, 데이터 수정으로 인한 충돌이 자주 발생하지 않을 것으로 예상되면서 조회가 자주 발생한다면 낙관적 락을 통해 성능을 향상시키는 것이 좋다.

참고