[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 낙관적 락과 비관적 락 기초