[JPA] Lock
JPA 에서의 Lock
JPA Lock
영속성 컨텍스트(1차 캐시)를 적절히 활용하면 DB 트랜잭션 격리 수준이 READ_COMMITTED여도 애플리케이션 레벨에서 REPEATABLE READ가 가능.
JPA는 DB 격리 수준을 READ COMMITTED 수준으로 가정. 만약 일부 로직에 더 높은 격리 수준이 필요하면 낙관적 락
과 비관적 락
중 하나를 사용.
🚀 낙관적 락
- 트랜잭션 대부분은 충돌이 발생하지 않는다고 낙관적으로 가정하는 방법.
- JPA에서 제공하는
버전 관리
기능 사용 - DB 제공 락 기능❌ , 애플리케이션 제공 락 ⭕️
- 트랜잭션을 커밋하기 전까지는 트랜잭션의 충돌을 알 수 없다는 특징
- 낙관적 락을 사용하기 위해서는
@Version
어노테이션을 사용해서 버전 관리 기능 추가해야 함
💻 @Version
적용 가능 타입
- Long (long)
- Integer (int)
- Short (short)
- Timestamp
@Entity
public class Board {
@Id
private Long id;
private String title;
@Version
private Integer version;
}
- 엔티티에 버전 관리용 필드를 하나 추가하고
@Version
어노테이션 붙임 - 엔티티를 수정할 때 마다 버전이 하나씩 자동으로 증가
- 본인 트랜잭션에서 수정한 엔티티를 반영하려고 할 때, 테이블의 데이터의 버전과 다르면 예외가 발생
💡 버전 정보를 사용하면 최초 커밋만 인정하기가 적용됨
- 버전은 엔티티의 값을 변경하면 증가함
🚀 비관적 락
- 트랜잭션 충돌이 발생한다고 가정하고 우선 락을 걸고 보는 방법.
- DB 제공 락 기능 사용 ⭕️ (ie. select for update)
참조
- 김영한님의 자바 ORM 표준 JPA 프로그래밍 : 16.1.2 낙관적 락과 비관적 락 기초