본문 바로가기
  • Where there is a will there is a way.
개발/java

JPA 락

by 소확행개발자 2020. 4. 25.

 

2020/04/23 - [개발/spring-boot] - spring transaction 이란

이전에 트랜잭션과 격리수준에 대해서 알아봤다.

 

트랜잭션의 격리수준을 보장하기 위해서 JPA 에서 락을 제공한다 이번 글에서는 JPA 의 락에 대해서 정리했다.

 

JPA 락

락은 낙관적인 락 비관적인 락이 있다.

  • 낙관적인 락

 트랜잭션 대부분은 충돌이 발생하지 않는다고 낙관적으로 가정하는 방법이다. 데이터베이스가 제공하는 락을 사용하지 않고 애플리케이션이 제공하는 락이다.

 

  • 비관적인 락

 트랜잭션은 충돌이 발생한다고 가정하고 우선 락을 건다. 

 

  • 두번 갱신 분실 문제 ( second lost updates problem )

두명이 동시에 같은 내용을 수정한다고 가정해보자

 두명이 비슷한 시기에 수정완료 버튼을 눌렀다면 결과적으로 먼저 완료한 사용자 A 의 수정사항은 사라지고 B 의 수정사항만 남게 된다.

 데이터베이스는 이런 갱신 분실문제를 해결하지 못하므로 JPA 에서 이를 해결해야 한다.

 

1. JPA 낙관적인 락

 

JPA 락은 조회할때 즉시 걸 수도 있고 필요할 때 락을 걸 수도 있다.

내가 사용하던 서비스는 repository extends 를 사용했다. 그래서 생각한게 만약 락을 사용하게 된다면 필요한 시점의 서비스 layer 에서 
em.lock(Entity, LockModeType.OPTIMISTIC)
을 하면되지 않을까?

JPA 가 낙관적인 락은 @Version 어노테이션을 entity 에 사용한다. 

자세한 사용방법은 책이나 인터넷이 나온다.

 

1.1 NONE

1.2 OPTIMISTIC

1.3 OPTIMISTIC_FORCE_INCREMENT

논리적인 단위로 엔티티 연관관계 주인을 관리할때 사용하는 방법이다.

연관관계 주인이 수정된다면, 부모 엔티티는 수정되지 않는다. 따라서 본래 되로라면 락을 걸 수 없지만 위와 같은 방법을 사용하면 부모 엔티티도 락을 걸 수 있다.

 

 

2. JPA 비관적인 락

 

JPA 비관적인 락은 위에 설명처럼 데이터베이스 트랜잭션 락 메커니즘에 의존하는 방법이다.

@Version 은 사용하지 않고 SQL 쿼리 ( select or update ) 구문을 사용하면서 시작한다.

 

비관적인 락은 스칼라 타입을 조회할 때도 사용할 수 있다. 

-> 스칼라 ( 영속성 컨텍스트가 관리하지 않는 객체 조회 ex ) 프로잭션 )

데이터를 수정하는 즉시 트랜잭션 충돌을 감지할 수 있다.

 

PESSIMISTIC WRITE

비관적 락이라 하면 일반적으로 이 옵션을 뜻한다. 데이터베이스에 쓰기 락을 걸때 사용한다.

 

PESSIMISTIC_READ

데이터를 반복 읽기만 하고 수정하지 않는 용도로 락을 걸 때 사용한다. ( 일반적으로 잘 사용하지 않는다고 함 )

 

PESSIMISTIC_FORCE_INCREMENT

비관적 락중 유일하게 버전 정보를 사용한다. 비관적 락이지만 버전 정보를 강제로 증가시킨다. 

 

비관적 락과 타임아웃

비관적 락을 사용하면 락을 획득할 때까지 트랜잭션이 대기한다. 무한정 기다릴 수는 없으므로 타임아웃 시간을 줄 수 있다.

 

 

'개발 > java' 카테고리의 다른 글

Iterator design pattern  (0) 2020.05.28
JPA 2차 캐시란  (0) 2020.04.26
JPA 기초 프록시란 무엇인가  (0) 2020.04.12
Java Collection 프레임워크  (0) 2020.03.22
heap 메모리와 Garbage Collector  (1) 2020.03.21

댓글