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 |
댓글