2024. 2. 15. 21:39ㆍspring/JPA
낙관적 락
JPA가 제공하는 낙관적 락은 버전(@Version)을 사용한다. 낙관적 락은 트랜잭션을 커밋하는 시점에 충돌을 알 수 있다는 특징이 있다.
락 옵션 없이 @Version만 있어도 낙관적 락이 적용된다. 락 옵션을 사용하면 더 세밀하게 락을 제어할 수 있다.
옵션
1. NONE
락 옵션을 적용하지 않아도 엔티티에 @Version이 적용된 필드만 있으면 낙관적 락이 적용된다.
- 용도
조회한 엔티티를 수정할 때 다른 트랜잭션에 의해 변경되지 않아야 한다. 조회 시점부터 수정 시점까지를 보장한다.
- 동작
엔티티를 수정할 때 버전을 체크하면서 버전을 증가한다. 이때 데이터베이스의 버전 값이 현재 버전이 아니면 예외가 발생한다.
- 이점
두번의 갱신 분실 문제를 예방한다.
2. OPTIMISTIC
@Version만 적용했을 때는 엔티티를 수정해야 버전을 체크하지만 이 옵션을 추가하면 엔티티를 조회만 해도 버전을 체크한다.
- 용도
조회한 엔티티는 트랜잭션이 끝날 때까지 다른 트랜잭션에 의해 변경되지 않아야 한다. 조회 시점부터 트랜잭션이 끝날 때까지 조회한 엔티티가 변경되지 않음을 보장한다.
- 동작
트랜잭션을 커밋할 때 버전 정보를 조회해서 현재 엔티티의 버전과 같은지 검증한다.
- 이점
DIRTY READ와 NON-REPEATABLE READ를 방지한다.
3. OPTIMISTIC_FORCE_INCREMENT
낙관적 락을 사용하면서 강제로 버전을 증가시킨다.
- 용도
논리적인 단위의 엔티티 묶음을 관리할 수 있다. 예를 들어 게시물과 첨부파일이 일대다, 다대일의 양방향 연관관계이고 첨부파일이 연관관계의 주인이다. 게시물을 수정하는데 첨부파일만 추가한다면 게시물의 버전은 증가하지 않는다.
=> (게시물 테이블은 변경되지 않았음)
해당 게시물은 물리적으로 변경되지 않았지만 논리적으로 변경되었다. 이때 게시물의 버전도 강제로 증가시킬 때 사용된다.
- 동작
엔티티를 수정하지 않아도 트랜잭션을 커밋할 때 UPDATE 쿼리를 사용해서 버전 정보를 강제로 증가시킨다.
- 이점
강제로 버전을 증가해서 논리적인 단위의 엔티티 묶음을 버전 관리할 수 있다.
비관적 락
JPA가 제공하는 비관적 락은 데이터베이스 트랜잭션 락 메커니즘에 의존하는 방법이다. 주로 SQL 쿼리에 SELECT FOR UPDATE 구문을 사용하면서 시작하고 버전 정보는 사용하지 않는다. 비관적 락은 주로 PESSIMISTIC_WRITE 모드를 사용한다.
비관적 락은 다음과 같은 특징이 있다.
- 엔티티가 아닌 스칼라 타입을 조회할 때도 사용할 수 있다.
- 데이터를 수정하는 즉시 트랜잭션 충돌을 감지할 수 있다.
옵션
1. PESSIMISTIC_WRITE
데이터베이스에 쓰기 락을 걸 때 사용한다.
- 용도
데이터베이스에 쓰기 락을 건다.
- 동작
데이터베이스 SELECT FOR UPDATE를 사용해서 락을 건다.
2. PESSIMISTIC_READ
데이터를 반복 읽기만 하고 수정하지 않는 용도로 락을 걸 때 사용한다. 일반적으로 잘 사용하지 않는다.
3. PESSIMISTIC_FORCE_INCREMENT
비관적 락중 유일하게 버전 정보를 사용한다. 비관적 락이지만 버전 정보를 강제로 증가시킨다.
'spring > JPA' 카테고리의 다른 글
트랜잭션과 락(2) - 락 기본 (0) | 2024.02.15 |
---|---|
트랜잭션과 락(1) (0) | 2024.02.15 |
성능 최적화(4) - 트랜잭션을 지원하는 쓰기 지연과 성능 최적화 (0) | 2024.02.15 |
성능 최적화(3) - 배치 처리 (0) | 2024.02.13 |
성능 최적화(2) - 읽기 전용 (0) | 2024.02.13 |