본문 바로가기
Back-end/JPA 개념

35. JPQL - 벌크 연산

by devraphy 2022. 5. 8.

0. 개요 

- 이번 포스팅에서는 벌크 연산에 대해서 알아보자.

 

 

1. 벌크 연산

a) 벌크 연산을 사용하는 이유

- 100개의 물건을 관리하는 Item 객체 있다고 해보자. 

- 물가 상승으로 인하여 모든 물건의 가격을 10% 인상하려고 한다면 어떻게 해야 할까?

 

- 지금까지 배운 방식으로 생각하면, 반복문을 통해 Item 객체를 탐색하면서 각 데이터를 가져온다.

- 그리고 JPA의 변경 감지 기능(= dirty checking)을 사용하여 객체의 값을 변경한다.

 

- 그러나 이 방식에는 한 가지 문제가 존재한다. 

- 100개의 물건 가격을 수정하기 위해서 100개의 update 쿼리가 발행된다는 것이다.

 

- 만약 100만 개의 물건 가격을 수정한다면 100만 개의 update 쿼리가 발행된다.

- 이러한 경우, 벌크 연산을 사용한다. 

 

 

b) 벌크 연산이란?

- 벌크 연산이란, 하나의 쿼리를 사용하여 다수의 데이터를 변경하는 기능이다.

- 즉, 하나의 쿼리로 다수의 Row를 변경할 수 있다.

 

- 벌크 연산은 Update와 Delete에 적용할 수 있다.

- Hibernate를 사용한다면 Insert 또는 Insert into ~ select ~ 문에서도 벌크 연산을 사용할 수 있다.

 

 

c) 벌크 연산 사용 - executeUpdate()

- 벌크 연산은 executeUpdate() 메서드를 통해 실행된다.

 

- 예를 들어, 모든 물건의 가격을 10% 인상한다고 해보자.

- 다음 같이 벌크 연산을 통해 데이터를 변경할 수 있다.

String query = "update Item i set i.price = i.price * 1.1";

int result = em.createQuery(query).executeUpdate();

 

- 위의 예시에서 볼 수 있듯이, executeUpdate()는 영향을 받은 데이터의 수를 반환한다.

 

 

d) 벌크 연산 사용 시 주의 사항

- 벌크 연산은 영속성 Context를 거치지 않고 DB에 직접 영향을 미친다.

- 그러므로 실제 DB의 값과 영속성 Context가 가지고 있는 값(= 1차 캐시에 저장된 값)이 다를 수 있다.

- 이 부분을 조심해야 한다.

 

- 이를 해결하기 위해서는 다음 2가지 해결책 중 하나를 수행하면 된다.

  → 다른 쿼리를 실행하기 전에 벌크 연산을 우선적으로 실행한다. (영속성 Context가 비어있는 상태)

  → 벌크 연산을 수행한 후 영속성 Context를 초기화한다. (em.clear()를 실행)

댓글