본문으로 건너뛰기

낙관적 락과 비관적 락

낙관적 락과 비관적 락은 데이터베이스 트랜잭션에서 동시성 제어를 위한 주요 기법입니다. 데이터 무결성을 유지하면서 여러 트랜잭션이 동시에 데이터에 접근할 때 발생할 수 있는 충돌을 해결할 때 사용됩니다.

✔️ 낙관적 락 (Optimistic Lock)

데이터 충돌이 적을 것으로 가정하고, 데이터를 읽을 때 락을 설정하지 않고 트랜잭션이 데이터를 수정할 때 충돌이 발생하지 않았는지 확인하는 방식입니다. 보통 version과 같은 별도의 구분 컬럼을 사용해서 데이터가 변경되었는지 확인하며, 충돌이 발생하면 데이터베이스가 아닌 애플리케이션에서 직접 롤백하거나 재시도 처리를 해야 합니다.

✔️ 비관적 락 (Pessimistic Lock)

데이터 충돌이 많을 것으로 가정하고, 트랜잭션이 시작될 때 공유락(Shared Lock, S-Lock) 또는 베타락(Exclusive Lock, X-Lock)을 설정하여 다른 트랜잭션이 해당 데이터에 접근하지 못하도록 하는 방식입니다.

S-Lock: 다른 트랜잭션에서 읽기는 가능하지만 쓰기는 불가능합니다.
X-Lock: 다른 트랜잭션에서 읽기, 쓰기 모두 불가능합니다.

cf. MySQL은 일관된 읽기(Consistent Nonlocking Reads)를 지원하여 X-Lock이 걸려 있어도 단순 SELECT로 읽을 수 있습니다.

MySQL에서는 단순 SELECT 문이 락이 걸린 row에 대해서 블로킹되지 않습니다. (InnoDB 엔진 기준, 기본 설정 기준)

MySQL의 InnoDB 스토리지 엔진은 MVCC(Multi-Version Concurrency Control)를 사용합니다.
즉, SELECT는 락을 걸지 않고, 트랜잭션 격리 수준에 따라 스냅샷된 데이터 버전을 읽습니다.

따라서 누군가 UPDATEDELETE로 특정 row에 쓰기 락을 잡고 있어도, SELECT * FROM table WHERE id = 1;같은 단순 조회는 락을 기다리지 않고 바로 실행됩니다.

✔️ 두 방식의 차이점은 뭘까?

낙관적 락은 충돌이 발생하면 해결하는 방식이고, 비관적 락은 애초에 충돌을 방지하는 방식입니다.

데이터 충돌이 자주 발생하거나 데이터 무결성이 중요한 경우에는 비관적 락을 사용하는 것이 유리할 수 있습니다.
조회 작업이 많고 동시 접근 성능이 중요한 경우에는 낙관적 락을 사용하는 것이 유리할 수 있습니다.

충돌 가능성

낙관적 락은 충돌이 자주 발생하지 않을 것이라고 가정하고, 비관적 락은 충돌이 자주 발생할 것이라고 가정합니다.

데이터베이스 락 사용 여부

낙관적 락은 락을 사용하지 않고, 비관적 락은 트랜잭션이 시작될 때 락을 설정합니다.

성능

낙관적 락은 락을 설정하지 않기 때문에 성능이 더 좋을 수 있습니다. 하지만 충돌이 발생할 경우 롤백하거나 재시도 처리를 해야 하기 때문에 성능이 떨어질 수 있습니다.
비관적 락은 락을 설정하기 때문에 다른 트랜잭션이 대기해야 하며, 이로 인해 성능이 저하될 수 있습니다.

Loading comments...