Dev

[JPA] 낙관적인 락과 비관적인 락 간단 정리

Ryan Woo 2020. 2. 11. 15:41

*아래 글은 김영한님의 '자바 ORM 표준 JPA 프로그래밍' 16장을 정리한 글입니다.
http://acornpub.co.kr/book/jpa-programmig

낙관적인락

  • JPA에서 제공하는 버전관리 기능을 사용 -> 어플리케이션 레벨의 락
  • 종류
    • READ -> OPTIMISTIC 과 같음(JPA 1.0 호환용)
    • WRITE -> OPTIMISTIC_FORCE_INCREMENT 과 같음(JPA 1.0 호환용)
    • NONE
        - 락 옵션을 적용안해도 엔티티에 버전 어노테이션 필드가 있으면 낙관적 락이 적용
        - 수정 시 업데이트 쿼리에 버전 비교, 버전이 다른경우 예외 발생
        - 두번의 갱신 분실 문제 해결
    • OPTIMISTIC
        - NONE + @Version은 업데이트시 버저 확인, OPTIMISTIC은 조회만 해도 버전을 체크
        - 한번 조회한 엔티티는 트랜잭션이 끝날때까지 다른트랜잭션에서 변경하지 않음을 보장 -> NON-REPEATABLE READ 방지
        - 트랜잭션을 커밋할때 버전 정보를 셀렉트, 같지않으면 예외 발생
    • OPTIMISTIC_FORCE_INCREMENT
        - 낙관적인 락을 사용하면서 버전정보를 강제로 증가시킴
        - 논리적인 단위의 엔티티 묶음을 관리
          게시물, 첨부파일 1:N, N:1 양방향 관계에서
          첨부파일만 하나 추가하면 해당 게시물은 물리적으로 변경되지 않았지만 논리적으로는 변경됨.
          이때 게시물의 버전도 강제로 증가시키려면 이 옵션을 사용.
        - 엔티티를 수정하지 않아도 트랜잭션으 커밋할때 업데이트 쿼리를 사용해 버전정보를 강제로 증가시킴.
          이때 데이터베이스 버전이 엔티티 버전과 다르면 예외 발생.
          추가로 엔티티 수정하면 수정 시 버전이 또 업데이트됨. 따라서 2번의 버전 증가가 나타날 수 있음.

비관적인락

  • DB에서 제공하는 락을 사용 -> 대표적으로 select for update 등
  • 종류
    • PESSIMISTIC_WRITE
        - 비관적인 락이라 하면 주로 이옵션. 데이터베이스에 쓰기 락.
        - select for update 등
        - NON-REPEATABLE READ 방지
    • PESSIMISTIC_READ
        - 데이터를 반복 읽기만 하고 수정하지 않는 용도로 락을 걸때 사용
        - 일반적으로 잘 사용 안함
        - 데이터베이스 방언에 의해 PESSIMISITIC_WRITE로 동작
            MySQL : lock in share mode
            postgresql : for share
    • PESSIMISTIC_FORCE_INCREMENT
        - 비관적인 락중에 유일하게 버전 정보를 사용
        - 하이버네이트는 nowait를 지원하는 DB에 대해서 for update nowait 옵션을 적용(오라클, postgresql)
        - nowait를 지원하지 않으면 for update가 사용됨.

비관적인 락과 타임아웃

  • 비관적인 락을 사용하면 락을 획득할때 까지 트랜잭션이 대기함
  • 타임아웃 시간을 설정(DB에 따라 동작 안할수도 있음)