-
격리 전략
JPA는 데이터 베이스 트랜잭션 격리 수준을 Read Committed을 기본으로 사용하며, 더 높은 격리 수준이 필요한 경우 낙관적 락이나 비관적 락을 사용해야 한다.
낙관적 락(Optimistic Lock)
낙관적 락은 엔티티의 Version 필드를 검사해서 버전정보를 체크하여 업데이트를 처리하는 방법이다. (애플리케이션에서 제공하는 락)
엔티티에서 버전정보로 사용할 필드에 @Version 어노테이션을 부여하고 테이블에 버전 정보로 사용할 컬럼을 생성해야 한다.
UPDATE table SET col = ? Version = Version + 1 (트랜잭션이 UPDATE 할 때 마다 버전 값 증가) WHERE ID = ? AND Version = ? (버전 비교)
위의 쿼리를 실행했을 때, 변경된 row의 수가 0이면 다른 트랜잭션이 데이터를 변경한 것으로 판단하고 Exception을 발생시킨다.
모드
JPA는 두가지의 낙관적 락 모드를 지원한다.
- OPTIMISTIC (Read)
- @Version 필드를 포함하는 모든 엔티티에 대해 낙관적 락을 얻는다.
- 이를 통해 Dirty Read와 Non-Repeatable Read를 방지한다.
- OPTIMISTIC_FORCE_INCREMENT (Write)
- 낙관적 락을 사용하면서 버전 정보를 증가시킨다.
비관적 락 (Pessmitic Lock)
비관적 락은 트랜잭션의 충돌이 발생한다는 것을 가정하고 데이터 베이스가 제공하는 락을 거는 방법이다.
두가지 타입이 있는데, 배타적 락 (Exclusive Lock)과 공유 락 (Shared Lock)이 있다.
배타적 락은 데이터를 변경하고자 할 때 사용되며, 트랜잭션이 완료될 때 까지 유지되어 해당 락이 해제될 때까지 다른 트랜잭션이 접근하지 못하도록 방지한다.
공유 락은 다른 트랜잭션이 동시에 데이터를 읽을 수는 있지만 쓰기 작업을 할 수 없도록 방지한다.
모드
JPA는 세가지의 비관적 락 모드를 지원한다.
- PESSIMISTIC_READ
- 공유 락을 얻고 데이터가 업데이트 되거나 삭제되는 것을 방지한다.
- PESSIMISTIC_WRITE
- 배타적 락을 얻고 데이터를 읽거나, 업데이트, 삭제 하는 것을 방지한다.
- PESSIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_WRITE와 유사하게 작동하며, 엔티티의 버전 속성을 추가로 증가시킨다.
참고
'Java > JPA' 카테고리의 다른 글
트랜잭션, 동시성 (0) 2020.10.25 영속성 컨텍스트 (0) 2020.10.23 JPA(Java Persistence API) (0) 2020.08.07 - OPTIMISTIC (Read)