본문 바로가기
Jpa/querydsl

[Querydsl 5편] querydsl 조회 시 영속성 컨텍스트 이슈, JPA 벌크 연산 이슈

by 무대포 개발자 2022. 10. 5.
728x90
반응형

source 는 Github 에 있습니다.

목차는 Querydsl 목차 에 있습니다.

[Querydsl 5편] querydsl 조회 시 영속성 컨텍스트 이슈, JPA 벌크 연산 이슈

Querydsl 이란?

  • querydsl 이란 JPQL 을 만들어주는 builder 입니다. 최종적으로는 JPQL 로 변환됩니다.
  • 즉, 코드로 JPQL 을 작성할 수 있으며, 코드 작성 단계에서 문법적 에러를 확인할 수 있습니다.

JPQL 이란?

  • Java Persistence Query Language 약자입니다.
  • SQL을 추상화한 객체지향쿼리 언어입니다. JPQL은 엔티티 객체를 대상으로 쿼리를 작성합니다. 최종적으로 JPQL 또한 SQL 로 변환이 됩니다.
  • JPQL은 SQL을 추상화하기 때문에 특정 데이터베이스 SQL에 의존하지 않습니다.

JPQL 예시

select m from Member as m where m.name = 'Lee'

Querydsl 조회 시, 영속성 컨텍스트 이슈

  • JPA 에서 findBy식별자 는 영속성 컨텍스트를 먼저 조회한 후, 없으면 데이터베이스를 조회합니다.

    • 식별자가 아니면 1차 캐시를 사용하지 않습니다. 왜냐하면 식별자가 아닌 값으로 조회했을 때, 중복된 값을 조회해버리면 상당히 복잡해지기 때문입니다.
  • JPQL 의 경우 데이터베이스를 먼저 조회한 후, 영속성 컨텍스트에 값이 들어있으면 버리고 없으면 저장합니다.

  • querydsl 은 JPQL 로 변환됩니다. JPQL 은 조회할 때, 영속성 컨텍스트를 먼저 조회하지 않고, 데이터베이스를 먼저 조회합니다.

  • 데이터베이스에서 조회해 온 값을 영속성 컨텍스트에 넣을려고 합니다.

  • 이 때, 영속성 컨텍스트에 이미 데이터가 있다면 데이터베이스에서 조회해 온 값을 버립니다.

    • 이렇게 하는 이유는 영속성에도 값과, 데이터베이스에 읽어온 값이 충돌하며 이는 DIRTY READ 가 발생한는 것이며, (영속성 컨텍스트에 있는 값을 변경중일 수 있으니) 데이터베이스에서 조회한 값을 버림으로써 NON-REPEATABLE READ 발생 도 막는 것입니다.
  • 그렇기에 JPA 내부에서 위와 같이 동작함으로 애플리케이션 레벨에서 REPEATABLE READ 레벨로 동작하게 됩니다.
  • 위와 같은 문제를 해결하기 위해서 데이터를 조회하기 전에 영속성 컨텍스트를 초기화하는 방법이 있습니다.

JPA 벌크 연산 이슈

  • JPA 에서 벌크 연산을 사용 시, 데이터베이스에 직접 쿼리를 날립니다.
    • executeUpdate() 메소드를 사용해서 버퍼에 데이터를 insert 합니다.
  • 이 때, 주의할점은 영속성 컨텍스트에 이미 값이 있고, 이 값을 변경해서 벌크 연산을 날릴 경우 조회되는 값은 영속성 컨텍스트에 있는 값입니다. 이 점을 주의해야 합니다.
  • 해결 방법으로는 영속성 컨텍스트를 refresh, clear 하는 방법이 있습니다.

Reference

댓글