비관적 락, 낙관적 락
서버개발

비관적 락, 낙관적 락

  • Lock이란
    • DB 충돌 상황을 개선하기 위해 사용하는 것
    • 방법
      • 테이블의 row에 접근 시 lock을 걸고 다른 lock이 걸려 있지 않는 경우에만 수정이 가능하도록 설정
      • 수정할 때 내가 먼저 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것

  • 낙관적 락(Optimistic Lock)
    • 이론
      • 수정할 때 내가 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것
        (주로 versioning)
      • DB에서 제공하는 것이 아닌 어플리케이션 레벨에서 잡아주는 Lock
      • 애시당초 버전을 동시에 select query에 사용하기 때문에 해당 row가 update된 경우 찾을 수 없음
      • hashcode와 timestamp를 이용하기도 한다

  • 비관적 락(Pessimistic Lock)
    • 이론
      • 선전 잠금
      • 트랜잭션끼리의 충돌을 발생한다 가정하고 미리 락을 거는 것
      • DB에서 제공하는 락 기능 사용
      • Repeatable Read, Serializable 급의 격리 수준 제공
    • 사용법
      • 작동원리
        • 쿼리를 다음(select for update)과 같이 나가게 하여 업데이트 용으로 해당 데이터를 찾는 것이니 다른 곳에서 건들 수 없도록 하라는 것
      • Hibernate: select home0_.idx as idx1_0_, home0_.address as address2_0_, home0_.name as name3_0_, home0_.price as price4_0_ from home home0_ where home0_.name=? for update
      • 종류
        • LockModeType.PESSIMISTIC_WRITE
          • 일반적인 비관적 락으로, 다른 트랜잭션에서 읽지도 쓰지도 못함
          • 베타적 잠금
        • LockModeType.PESSIMISTIC_READ
          • 반복 읽기만 하고 수정하지 않는 용도로 락을 걸 때 사용
          • 다른 트랜잭션에서 읽기는 가능함
        • LockModeType.PESSIMISTIC_FORCE_INCREMENT
          • 버저닝을 위한 비관적 락

  • 롤백
    • 2개 이상의 row를 업데이트하다 1번째 row를 완료하고 2번째에서 충돌이 발생한 경우, 롤백이 발생한다
    • 낙관적 락의 경우
      • 충돌이 발생하여 수정을 못한 부분에 대해서는 롤백에 대한 책임을 어플리케이션 단으로 주어 어플리케이션에서 수동으로 롤백해주어야 한다
    • 비관적 락의 경우
      • 하나의 트랜잭션에 두 row를 수정하는 쿼리가 묶여있기 때문에 모두 롤백된다
    • 사용하는 경우
      • 낙관적 락은 트랜잭션을 필요로 하지 않아 성능적 우수
      • 트랜잭션을 타지 않기 때문에 충돌이 많이 일어나지 않을 것이라고 보여지는 곳에서 좋은 성능을 기대
      • 그러나 롤백이 되는 경우, 충돌이 났다고하면 이를 개발자가 수동으로 처리해주어야 하기 때문에 공수가 필요하고 버그가 발생할 수 있다