1. 벌크 연산
1) 벌크 연산이란?
- 성능을 위해 엔티티를 한 번에 수정하거나 삭제하는 연산을 의미한다.
- UPDATE와 DELETE 모두 executeUpdate() 메소드를 사용하면 된다. INSERT 벌크 연산은 JPA 표준은 아니지만 Hibernate에서는 지원한다.
int resultCount = em.createQuery("[UPDATE/DELETE SQL]")
.setParameter("price", 200)
.executeUpdate(); // 영향 받은 엔티티의 건수를 반환
- QueryDSL을 이용하는 방법은 https://kimcoder.tistory.com/495의 [11.배치 쿼리]를 참고하자.
- 벌크 연산은 영속성 컨텍스트를 무시하고 DB에 직접 쿼리한다.
2) 일관성 문제 해결
- 영속성 컨텍스트를 무시하고 DB에 직접 쿼리하게 되면 일관성 문제가 발생할 수 있다. 변경된 내용이 DB에만 반영되고 영속성 컨텍스트에는 기존 내용이 그대로 남아있게 되는 것이다. 이러한 문제를 해결하기 위한 3가지 방법이 있다.
- EntityManager.refresh() 사용 : DB로부터 엔티티를 다시 조회한다.
- 벌크 연산을 먼저 실행
- 벌크 연산 수행 후 영속성 컨텍스트 초기화 : EntityManager로 엔티티 조회를 시도하면 가장 먼저 영속성 컨텍스트에서 엔티티를 찾아보고 엔티티를 찾지 못했다면 DB를 조회한다는 특징을 이용한 방법이다. 영속성 컨텍스트를 초기화해두면 엔티티를 조회할 때 DB에 있는 데이터를 불러오게 된다.
2. EntityManager.find() vs JPQL
- EntityManager.find()는 영속성 컨텍스트를 DB보다 먼저 조회한다. 영속성 컨텍스트에서 엔티티를 찾았다면 DB를 조회하지 않고 영속성 컨텍스트에 있던 엔티티를 반환한다.
- JPQL은 DB를 영속성 컨텍스트보다 먼저 조회한다. 영속성 컨텍스트에 같은 엔티티가 있다면 DB로 조회한 엔티티는 버리고 영속성 컨텍스트에 있던 엔티티를 반환한다.
=> 전자가 성능상 이점이 있다.
3. FlushMode
- 기본적으로 commit이나 쿼리 실행 직전에 자동으로 flush()가 호출된다. JPQL 쿼리의 경우에는 일관성 문제를 방지하기 위해 기본적으로 flush()가 미리 호출되는 것이다.
- EntityManager.setFlushMode()로 flush 모드를 지정할 수 있으며, 인자로 javax.persistence.FlushModeType을 선택할 수 있다. 제공되는 옵션은 아래 내용을 참고하자.
FlushModeType.AUTO // (기본값) Commit 또는 JPQL쿼리 실행 시에 flush
FlushModeType.COMMIT // Commit할 때만 flush
참고로, Query 객체에도 setFlushMode()를 사용할 수 있다. 특정 쿼리에서만 다른 flush 모드를 사용하고 싶다면 Query 객체에 flush 모드를 지정하면 된다. Flush 모드는 EntityManager 설정보다 Query 설정이 우선권을 가진다.
em.setFlushMode(FlushModeType.COMMIT); // 2순위
Member member = em.createQuery(...)
.setFlushMode(FlushModeType.AUTO) // 1순위
.getSingleResult();
- Flush 모드는 웬만하면 기본값으로 충분하지만, 성능 최적화시에 flush 모드를 FlushModeType.COMMIT으로 바꿔야 할 수도 있다. Flush가 너무 자주 일어나는 상황이라면 flush 횟수를 줄이기 위해 COMMIT 모드를 고려해볼만 하다.
- JPA와 달리 비 ORM 기술은 보통은 캐시를 적용하지 않기 때문에, 비 ORM 기술과 트랜잭션을 공유하는 경우에는 비 ORM 기술의 쿼리를 실행하기 직전에 flush()를 호출해서 영속성 컨텍스트의 내용을 DB에 동기화해주는 것이 안전하다.
● 참고자료 : 자바 ORM 표준 JPA 프로그래밍
'Spring 사전 준비 > JPA Hibernate' 카테고리의 다른 글
[JPA] Spring Data JPA(2) (0) | 2022.08.20 |
---|---|
[JPA] Spring Data JPA(1) (0) | 2022.08.19 |
[JPA] 스토어드 프로시저 (0) | 2022.08.14 |
[JPA] 네이티브 SQL (0) | 2022.08.11 |
[JPA] QueryDSL (0) | 2022.08.10 |
댓글