낙관적 락 (Optimistic Lock)
트랜잭션 대부분은 충돌이 발생하지 않을 것이라고 낙관적으로 접근하는 방식
어플리케이션 레벨에서 Lock 을 건다.
데이터를 읽는 시점에 Lock을 걸지 않고, 수정을 하려고 할때 데이터가 변경되었는지 확인하고 데이터를 변경을 시도한다.
@Version
JPA의 @Version 어노테이션을 제공하고 있다.
엔티티가 수정될때 마다 자동으로 버전을 증가 시키며, 커밋을 하기 전에 엔티티의 버전과 DB의 버전이 같은지 확인을 한다.
버전이 다르면 OptimisticLockException 을 발생 시킨다.
지원하는 타입은 long, Long int, Integer, short, Short, timestamp
@Version
private Integer version;
update {table}
set
{column} = ?,
version = ? (버전 증가)
where
id = ?
and version = ? (버전 비교)
비관적 락 (Prssimistic Lock)
트랜잭션이 충돌이 발생할 것이라고 비관적으로 생각하고 우선 락을 거는 방식
데이터베이스 레벨에서 Lock 을 건다.
배타적 잠금(Exclusive Lock)과 공유 잠금(Shared Lock) 두가지 타입이 있다.
공유 잠금(읽기 잠금) : 다른 사용자가 동시에 데이터를 읽을 수는 있지만 Write는 할 수 없다.
베타적 잠금(쓰기 잠금) : 데이터를 변경하고자 할 때 사용되며, 트랜잭션이 완료될 때까지 유지되어 해당 Lock이 해제될 때까지 다른 트랜잭션은 해당 데이터에 읽기를 포함하여 접근을 할 수 없다.
베타적 잠금 예시)
entityManager.find(Student.class, 1L, LockModeType.PESSIMISTIC_WRITE, properties);
select {column...}
from student
where ... for update
하지만 샘플코드로 FOR UPDATE쿼리로 락을 걸었을때 UPDATE, DELETE는 대기상태로 들어가지만 SELECT쿼리는 수행이된다. 좀 더 조사해보니 FOR UPDATE가 붙은 SELECT쿼리만 동시성이 보장되고 일반적인 SELECT 쿼리를 날렸을 때는 따로 락이 걸리진 않는다. 하지만 그 트랜잭션안에서 update가 발생되면 그 update쿼리는 락이 걸린다.
반응형
'개발관련' 카테고리의 다른 글
MSA 에서 Service Mesh 란? (0) | 2020.05.19 |
---|---|
MSA 분산 트랜잭션 (0) | 2020.04.27 |
Webflux vs WebMvc 성능 비교 (0) | 2020.04.06 |
Spring Webflux Cold / Hot 이해하기 (0) | 2020.03.29 |
Spring Webflux, 이해하고 사용하자 (0) | 2020.03.21 |