비관적 락(Pessimistic Locking) 이란
- 동시성 제어 기법중 비관적 락은 트랜잭션이 데이터에 대한 엑세스를 시도할 때 미리 해당 데이터를 잠궈서 충돌을 해결하는 방식.
- 트랜잭션이 데이터를 읽거나 수정하기 전에 해당 데이터를 잠금(락)을 획득하여 다른 트랜잭션의 엑세스를 막음.
- 데이터베이스에서는 주로 SELECT ... FOR UPDATE와 같은 명령어를 사용하여 비관적 락을 구현.
- 비관적 락은 데이터를 수정하는 작업이 많거나 동시에 여러 트랜잭션이 데이터를 수정하는 환경에서 사용.
JPA 비관적 락 활용
JPA가 제공하는 비관적 락은 데이터베이스 트랜잭션 락 메커니즘에 의존하는 방법이다. 주로 SQL 쿼리에 select for update 구문을 사용하면서 시작하고 버전 정보는 사용하지 않는다. 비관적 적락은 주로 pessmistic_write 모드를 사용한다.
비관적 락은 다음과 같은 특징이 있다.
- 엔티티가 아닌 스칼라 타입을 조회할 때도 사용할 수 있다.
- 데이터를 수정하는 즉시 트랜잭션 충돌을 감지할 수 있다.
public interface SearchHitRepository extends JpaRepository<SearchHit, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select h from SearchHit h where h.id = :id")
SearchHit findByIdForUpdate(Long id);
}
비관적 락에서 발생하는 예외
- PessmisticLockException
- PessmisticLockingFailureException(스프링 예외 추상화)
비관적 락 충돌 해결 전략
1. Pessmistic_write
비관적 락이라 하면 일반적으로 이 옵션을 뜻한다. 데이터 베이스에서 쓰기 락을 걸 때 사용한다.
- 용도 : 데이터 베이스에 쓰기 락을 건다.
- 동작 : 데이터베이스 select for update 를 사용해서 락을 건다.
- 이점 : non-reatable read를 방지한다. 락이 걸린 row는 다른 트랜잭션이 수정할 수 없다.
2. Pessmistic_read
데이터를 반복 읽기만 하고 수정하지 않는 용도로 락을 걸 때 사용한다.
데이터 베이스 대부분은 방언에 의해 pessmistic_Write로 동작하기 때문에 일반적으로 잘 사용하지 않는다.
Mysql : lock in share mode
PstgreSql : for share
3. Pessimstic_force_increment
비관적 락 중 유일하게 버전 정보를 사용한다. 비관적 락이지만 버전 정보를 강제로 증가시킨다.
하이버네이트는 nowait를 지원하는 데이터베이스에 대해서 for update nowait 옵션을 적용한다.
오라클 : for update nowiat
PostgreSQL : for udpate nowait
nowiat를 지원하지 않으면 for update가 사용된다.
비관적 락과 타임아웃
비관적 락을 사용하면 락을 획득할 떄까지 트랜잭션이 대기한다. 무한정 기다릴 수는 없으므로 타임아웃 시간을 줄 수 있다.
Map<String, Object> propertis = new HashMap<>();
properties.put("javax.persistence.lock.timeout", 1000);
Board board = em.find(Board.class, "boardId", LockModType.PESSimistic_wirte, properties);
'Spring > JPA' 카테고리의 다른 글
트랜잭셔널 전파 (0) | 2024.03.12 |
---|---|
성능 향상을 위한 1차 캐시와 2차 캐시 (0) | 2023.12.31 |
JPA 낙관적 락 (1) | 2023.12.07 |
영속성 컨텍스트란? (0) | 2023.12.03 |
JPQL 이란? (0) | 2023.12.02 |