본문 바로가기
개발관련

Optimistic Lock과 Pessimistic Lock

by 부발자 2020. 4. 15.

낙관적 락 (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