[JPA] 벌크 연산

jimmy·2025년 3월 26일
post-thumbnail

벌크 연산이란 한 번의 SQL 쿼리로 여러 개의 데이터를 수정하거나 삭제하는 기능이다.

특정 조건인 엔티티에 대해서 값을 동시에 변경할 때, 변경 감지를 사용하면 update sql이 너무 많이 실행될 수 있기 때문에, 벌크 연산을 사용하는 것이 좋다.

순수 JPA에서 벌크 연산

 String qlString = "update Product p " + 
                  "set p.price = p.price * 1.1 " +  
                  "where p.stockAmount < :stockAmount";  
int resultCount = em.createQuery(qlString) 
                    .setParameter("stockAmount", 10)  
                    .executeUpdate(); //영향받은 엔티티 수 반환
  • executeUpdate()를 사용하여 벌크 연산을 실행하며, 영향을 받은 엔티티 수를 반환한다.

Spring Data JPA에서 벌크 연산

@Modifying
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
  • @Modifying 어노테이션을 사용하여 데이터 변경 쿼리임을 명시한다.
  • @Modifying(clearAutomatically = true) (기본값 false) 옵션을 사용하면, 벌크 연산 후 영속성 컨텍스트를 자동으로 초기화하여 데이터 불일치 문제를 방지할 수 있다. 벌크 연산 후 다시 조회해야 하는 경우에 이 옵션을 설정하자.

벌크 연산은 DB에 직접 적용된다.

벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 바로 쿼리를 날린다. (flush는 commit이나, 쿼리가 나갈 때 호출된다. 따라서 벌크 연산 쿼리가 나갈 때 flush가 되는 것이다.)
→ 영속성 컨텍스트에 값이 있는 경우, 벌크 연산을 하고 난 후 초기화를 하지 않으면, 영속성 컨텍스트에 있는 값은 최신 db 상태가 아니라서 데이터 불일치 문제가 발생할 수 있다.

해결 방법

  • 영속성 컨텍스트에 아무것도 없을 때는 벌크 연산을 먼저 실행
  • 벌크 연산 수행 후 영속성 컨텍스트 초기화
    → em.clear()나 @Modifying(clearAutomatically = true)옵션 활용

참고
자바 ORM 표준 JPA 프로그래밍 - 기본편,
실전! 스프링 데이터 JPA

profile
백문이 불여일기

0개의 댓글