낙관적 락 (Optimisstic Lock)
낙관적 락 (Optimisstic Lock) 이란?
- 락이 생길 경우가 없다고 낙관할때
- 어플리케이션 레벨에서 제공하는 Lock 기능을 사용
- JPA가 제공하는 엔티티의 버전 관리 기능을 사용
- 트랜잭션 커밋 전에는 트랜잭션 충돌을 알 수 없음
JPA가 제공하는 낙관적 락 옵션(LockModeType)
- NONE : 엔티티를 수정하는 시점에 버전이 증가함
(엔티티에 @Version이 있으면 기본으로 적용되는 락 옵션) - OPTIMISTIC : 엔티티를 조회하는 시점에 버전이 증가함
(Dierty Read 와 Non-Repeatable Read를 방지) - OPTIMISTIC_FORCE_INCREMENT : 논리적으로 변경되었을 경우도 버전이 증가함
(자식 엔티티만 변경되도 부모 엔티티의 버젼이 강제 증가)
* Non-Repeatable Read 이란 한 트랜잭션내에서 같은 쿼리를 두 번 수행했을 때, 결과가 다르게 나타나는 현상을 의미함
낙관적 락 옵션(LockModeType) 적용 예제
@Repository
public interface UserMasterJpa extends JpaRepository<UserMasterEntity, String> {
/**
* JPA가 제공하는 낙관적 락 옵션(LockModeType)
* LockModeType.NONE <-- Entity 에 @Version 있다면 Default 임
* LockModeType.OPTIMISTIC
* LockModeType.OPTIMISTIC_FORCE_INCREMENT
*/
@Lock(LockModeType.OPTIMISTIC)
Optional<UserMasterEntity> findByUserId(Long id);
}
버젼 명시 예제
public class UserMasterEntity {
@Id
@Column(name = "USER_ID", nullable = false, length = 5)
private String userId;
@Version
@Column(name = "DATA_VERSION", nullable = true, precision = 0)
private Integer dataVersion;
}
Lock 을 사용함에 따라 발생할 수 있는 예외
- ObjectOptimisticLockingFailureException
(트랜잭션 커밋 시점에 버전이 같지 않으면 발생하는 예외)
사용시 주의사항
- DB-Lock 을 사용하지 않지만 Dead-Lock이 발생할 수 있음
(x-Lock이 사용될 경우) - 롤백(Rolback) 이슈(어플리케이션 단에서 롤백을 수행해야 함)
* Update 쿼리에 사용되는 모든 레코드에 exclusive lock(x-Lock)을 설정한다고 한다
락이 생길 경우가 없다고 낙관할때 사용하는게 좋아보임
(충돌이 예상되거나 충돌이 발생했을 때 비용이 많이 들것이라고 판단되는 곳에서는 사용하지 않는 것이 좋음)
'Java > JPA' 카테고리의 다른 글
JPA의 비관적 락을 통해 엔티티에 대한 동시성 문제해결 (0) | 2023.09.02 |
---|