본문 바로가기
Spring|Spring-boot/Spring-Data-JPA

벌크성 수정 쿼리

by oncerun 2022. 11. 27.
반응형

 

최근 데이터의 순서를 사용자의 요청마다 빠르게 변경해야 할 일이 생겼다. 

 

그런데 이 과정은 단순하게 해당 위치에 데이터를 넣는 것이 아니라 변경된 순서와 기존 순서에 비교에 따라 로직이 달라져야 한다. 

 

기존 순서보다 변경된 순서가 크다면 변경된 순서 위치에 있는 데이터부터 기존 위치 전에 위치한 데이터를 하나씩 앞으로 변경해주어야 했고

 

기존 순서보다 변경된 순서가 작다면 기존 순서위치에 있는 데이터부터 변경된 순서 위치 전 데이터까지 하나씩 뒤로 밀어주어야 한다. 

 

만약 해당 범위가 크다면 어떻게 될까?

 

기존 JPA를 사용하여 이를 처리할려면 다음과 같은 로직이 필요하다.

 

조건에 맞는 데이터 순서를 가진 모든 데이터를 가져온다. 

순회하면서 데이터를 앞 혹은 뒤로 순서를 변경해준다. 

 

여기서 중점은 순회다. 많은 데이터일 수록 이는 성능에 영향을 줄 수 있다고 생각했다. 

 

해당 데이터 만큼 update 쿼리가 발생할 것이기 때문인데, 따라서 벌크성 쿼리를 사용해야 한다고 판단하여 적용한 적이 있다. 

 

내가 진행한 방법이 맞는지 스프링 데이터 JPA의 벌크성 수정 쿼리를 한번 공부를 진행해보자. 

 

기존 JPA를 활용하여 벌크성 업데이트를 진행 한다면 다음과 같이 사용할 수 있을 것이다.

public int bulkAgePlus(int age) {
    return em.createQuery("update Member m set m.age = m.age + 1 where m.age >= :age")
            .setParameter("age", age)
            .executeUpdate();
}

 

그럼 스프링 데이터 JPA는 어떻게 처리할까?

@Modifying
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);

 

executeUpdate를 표현하기 위해 @Modifying 어노테이션이 추가된 것 외에 기본적으로 사용법이 크게 다르지 않다.

 

벌크 연산 특성 상 영속성 콘텍스트를 업데이트하지 않고 데이터베이스에 직접 질의한다. 

그렇기 때문에 동기화가 필요하거나 영속성 콘텍스트를 사용하는 부분 중간에 벌크성 연산을 하면 문제가 발생한다. 

 

나는 실무에 적용할 때 데이터의 순서를 변경하는 로직을 벌크성 쿼리 단 한 개만 작성했다. 

다른 API를 통해 순서를 수정 시 해당 순서를 변경을 하는 부분이 있다면 데이터 정합성 문제가 발생할 것 같았기 때문이다. 

물론 트랜잭션 시 해당 테이블 락을 통해 안전하게 처리할 수 있겠지만 동시에 여러 개를 신경 쓰고 싶지 않았던 의도도 크고 벌크성 쿼리 락에 걸리는 시간이 매우 짧을 것이라고 예상되기 때문이다.

 

만약 데이터의 수정과 순서 수정을 같이 해야한다면 다음과 같이 사용할 것이다.

 

1. 벌크성 수정 쿼리 실행

 

2. 영속성 컨텍스트 clear()

 

3. 조회 및 수정

 

4. 변경 감지 수정

 

더 좋은 다른 방법이 있을 수 있어도 현재 상황에는 다음과 같이 적용한 것 같다.

 

 

만약 clear 작업을 수동으로 하는 것이 불편할 수 있다. 이는 엔티티 매니저의 종속성을 별도로 필요하기 때문인데, 스프링 데이터 JPA는 다음과 같이 어노테이션의 옵션을 통해 clear를 자동적으로 호출해줄 수 있다.

@Modifying(clearAutomatically = true)

 

 

 

 

반응형

'Spring|Spring-boot > Spring-Data-JPA' 카테고리의 다른 글

Custom Repository  (0) 2022.11.30
JPA Hint & Lock  (0) 2022.11.27
@EntityGraph  (0) 2022.11.27
스프링 데이터 JPA  (0) 2022.11.26
Spring-Data-JPA 소개  (0) 2022.10.20

댓글