[JPA]@Version 어노테이션에 대해여

@Version 어노테이션의 역할

  1. 버전 관리
    1. @Version 은 엔티티 필드에 적용되며 해당 필드를 버전 관리용으로 사용
  1. 자동 버전 증가
    1. 엔티티가 수정시마다 필드값이 자동으로 증가한다.
  1. 데이터 일관성 유지
    1. 트랜잭션 중 엔티티의 버전이 변경시, 이는 다른 트랜잭션이 해당 엔티티를 수정했음을 의미
    1. 경우 예외가 발생하며 데이터의 일관성 유지가능

낙관적 락 테스트

@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString
public class Item {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private float price;
    private int stockQuantity;
    
    @Version
    private int version;
@Test
    public void testOptimisticLock() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<?> future = executorService.submit(
            () -> itemService.updateItem(1L, "modi1", 123));
        Future<?> future2 = executorService.submit(
            () -> itemService.updateItem(1L, "modi2", 345));
        
        Exception result = new Exception();
        
        try {
            future.get();
            future2.get();
        } catch (ExecutionException e) {
            result = (Exception) e.getCause();
        }
        
        assertThat(result).isInstanceOf(OptimisticLockingFailureException.class);
    }
  • 일단 하나의 Item 이 이미 데이터에 들어가있다고 생각하고
  • 스레드2개가 동시에 업데이트를 수행한다고 치면
  • 하나의 트랜잭션은 실패하고 OptimisticLockingFailureException 가 발생해야한다.
  • 수행결과

특이한점

UPDATE 쿼리가 수행된 것을 보면

update item set name='modi2', price=0.0, stock_quantity=345, version=1 
where id=1 and version=0;
update item set name='modi1', price=0.0, stock_quantity=123, version=1 
where id=1 and version=0;
  • 일단 첫번째 수행된 쿼리로 업데이트되긴하며,
  • 다음 버전을 +1 하여 update 치는것 같다.

Uploaded by N2T