비관적 락

낙관적 락

비관적 락(pessimistic lock)

비관적 락 테스트 코드

트랜잭션 동시성 제어 문제가 발생할 것이라고 가정하여 리소스에 대한 접근을 제어하기 위해 데이터베이스에서 락을 명시적으로 설정하는 방식이다

트랜잭션이 실행되는 동안 데이터에 읽기 락 또는 쓰기 락을 설정하여 다른 트랜잭션이 해당 데이터에 접근하거나 수정하지 못하도록 한다

락 획득 대기 시간을 지정하여 일정 시간이 지나면 실패로 처리할 수도 있다

비관적 락 종류

비관적 읽기 락

읽기 보호

사용

비관적 쓰기 락

읽기/쓰기 보호

사용

낙관적 락(optimistic lock)

비관적 락 테스트 코드

트랜잭션 동시성 제어 문제가 발생하지 않을 것이라고 가정하고 데이터베이스 락을 설정하지 않는 대신 애플리케이션 차원에서 버전 관리를 통해 방지한다

애플리케이션에서 엔티티의 버전을 변경하면 데이터가 커밋될 때 변경된 버전을 비교하여 충돌을 감지한다

낙관적 락은 데이터베이스에 커밋되기 전까지 충돌 여부를 알 수 없고 버전 검증을 통해 충돌이 발생되면 그에 대한 후처리를 수행한다

두 개의 트랜잭션에서 동시에 엔티티를 조회한 상황을 가정해보자

각 트랜잭션에서 엔티티를 수정하면서 정의된 버전의 값이 변경될 것이다

같은 버전의 엔티티를 조회했기 때문에 변경된 버전의 값도 동일하다

-- 비즈니스 로직 수행 --
트랜잭션 A, B -> 엔티티 조회 (버전: 1)
트랜잭션 A, B -> 엔티티 수정 
            -> 버전 변경(트랜잭션 A: 1 -> 2, 트랜잭션 B: 1 -> 2)

트랜잭션 A에서 먼저 커밋하여 엔티티의 버전도 변경한다

이후 트랜잭션 B가 커밋하는데 트랜잭션 A에서 변경한 버전과 동일한 버전인 것을 감지하여 예외가 발생한다 (버전 충돌)

트랜잭션 A 커밋 -> 엔티티 버전 업데이트 (버전: 2)
트랜잭션 B 커밋 -> 트랜잭션 B의 엔티티 버전: 2 
             -> 트랜잭션 A에서 커밋된 엔티티와의 버전 비교 -> 버전 충돌 

위의 방식이 기본적인 낙관적 락의 동작 방식이다

낙관적 락 종류

낙관적 읽기 락(optimistic read lock)

읽기 보호

동작

사용

낙관적 쓰기 락(optimistic write lock)

읽기/쓰기 보호

동작

사용

낙관적 락 충돌 처리 방법

충돌 발생 시 두 가지 방식으로 처리할 수 있다

  1. 재시도: 데이터를 다시 읽고 작업 재시도
  2. 롤백: 트랜잭션 롤백