JPA/JPQL

[JPA] 벌크(Bulk) 연산

IT록흐 2023. 6. 19. 14:05
반응형
 

[JPA] 영속성 컨텍스트의 이점

[JPA] JPA 동작원리 ( 영속성 컨텍스트 ) [JPA] 패러다임의 불일치 어플리케이션 개발은 주로 객체지향언어로 이루어진다. 객체지향언어는 현실의 많은 문제를 코드로 구현하지만 문제가 있다. 데이

lordofkangs.tistory.com

 

 

지난 포스팅에서 영속성컨텍스트의 이점에서 변경감지(DirtyChecking)를 다루어보았다.

 

엔티티에 변경사항이 감지되면 영속성컨텍스트는 자동으로 UPDATE,DELETE문을 생성하였다. 그러나 이 방법은 변경감지 한 건당 하나의 쿼리문을 생성한다. 만약 100개의 변경감지가 만들어졌다면 100개의 쿼리가 생성되어 실행된다. 이는 성능에 좋지 못하다. 그래서 UPDATE문,DELETE문을 JPQL로 만들어 여러 건의 변경및삭제를 가능하게 만들었는데, 이를 벌크연산이라 부른다. 

 

//UPDATE문
String jpql = "UPDATE Person p SET p.name = :newName WHERE p.id = :personId";
int updatedCount = entityManager.createQuery(jpql)
                .setParameter("newName", newName)
                .setParameter("personId", personId)
                .executeUpdate();

//DELETE문 
String jpql = "DELETE FROM Person p WHERE p.age = :age";
int deletedCount = entityManager.createQuery(jpql)
                .setParameter("age", age)
                .executeUpdate();

 

이로써 여러 건의 변경사항에 대응할 수 있게 되었다. 그러나 한 가지 주의점이 있다. 

 

JPQL은 파싱된 후, 영속성 컨텍스트를 거치지 않는다. 바로 데이터베이스에 실행된다.

 

 

 

 

엔티티매니저의 find메소드로 영속성컨텍스트에 Person엔티티 하나를 DB에서 조회했다고 가정해보자. 영속성 컨텍스트에 조회된 Person의 나이는 50이다. 

 

 

 

 

JPQL은 영속성컨텍스트를 거치지 않고 DB에 실행되므로 DB의 나이만 30으로 UPDATE된다. 영속성컨텍스트의 나이는 그대로 50이다. 여기서 데이터 정합성의 문제가 발생한다. 영속성컨텍스트를 초기화하지 않고 find메소드로 조회한다면 30이 아닌 50을 가져온다. 이처럼 벌크연산은 정합성을 깨뜨리는 문제를 발생시킬 수 있다. 

 

위 문제는 두 가지 방법으로 해결할 수 있다.

 

첫번째 방법 : 벌크연산부터 수행한다.

find 같은 영속성컨텍스트를 거치는 작업보다 벌크연산을 먼저 수행하는 방식으로 코드를 진행한다. 

 

두번째 방법 : 벌크연산 수행 후 영속성컨텍스트를 초기화한다. 

벌크연산이 수행되면 영속성컨텍스트의 내부데이터는 정합성이 깨져있다. entitymanger.clear()로 영속성컨텍스트를 초기화하여 정합성이 깨진 데이터를 조회하는 불상사를 차단한다. 

 

 


 

 

참고자료

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

반응형