본문 바로가기

spring/JPA

[JPA] 영속성 컨테이너 관련 의문점.

엔티디의 생명주기가 어떻게 되는가?

 

entity 생명주기

new : 식별자(id)가 존재하지 않은 새로운 엔티디

Managed : 영속성 컨테이너에 저장된 엔티디로서 무결성을 지니고 있다.

Detached : 식별자(id)가 존재하는 엔티디로서 무결성이 없다.

Removed : 삭제된 인스턴스

 

영속성 컨테이너는 쓰레드끼리 공유되는 객체인가?

영속성 컨테이너는 공유 자원이 아니다. 영속성 컨테이너는 하나의 요청(쓰레드)에서 사용하는 1차 캐시로서의 역할을 한다. 어플리케이션 단에서 공유되는 캐시 자원이 있는데 이 자원은 EntityManagerFactory를 통해서 얻을 수 있다.

 

EntityManagerFactory를 통해서 2차 캐시를 얻을 수 있다. 이때 2차 캐시는 어플리케이션 단에서 공유되는 캐시이다.

 

[JPA] 트랜잭션과 락, 2차 캐시

jpa-study에서 스터디를 진행하고 있습니다. 트랜잭션과 락 트랜잭션과 격리 수준 ACID 원자성 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하든가 모두 실패해야 한다.

steady-coding.tistory.com

 

영속성 컨테이너의 유지는 언제까지 되는가?

DB 커넥션을 반환할 때까지 유지된다. DB 커넥션을 어디서 반환할지는 설정할 수 있다.

이와 관련된 설정은 OSIV(open session in view)라고 한다.

JPA의 원천기술인 하이버네이츠에서는 EntityManager의 역할을 하는 Session이라는 인터페이스가 있다. 그래서 이 세션을 뷰단까지 열어둔다는 의미로 사용한 용어라고 추측된다.
spring.jpa.open-in-view:true or false

- 서비스 계층에서 반환

- 요청이 끝날 때까지 유지

DB 커넥션의 연결 구간을 짧게하면 커넥션 자원을 보다 절약할 수 있다.

길게하면 컨트롤러나 뷰단에서 지연로딩을 이용한 데이터 조회가 가능하다. 즉 편하다.

이러한 점을 고려하여 OSIV 설정을 해야한다.

 

em.flush()는 언제하는지?

  • 명시적으로 em.flush()를 호출하는 경우
  • 쿼리를 실행할 때
    • native query, jpql 과 같은 쿼리를 실행하는 경우는 주로 대량의 데이터를 추출하는 경우인데 이 때 이전에 영속성 컨테이너에 변경된 사항이 해당 쿼리에 영향을 미치는 경우가 있을 수 있기 때문에 flush()를 통해서 데이터 정합성을 유지하는 것
    • Spring Data JPA는 구현체로 Hibernate를 사용하고 있다. Spring Data JPA를 통해 Hibernate를 사용한다. 그 Hibernate에는 FlushModeType enum class가 있다. 그 값으론 AUTO와 COMMIT이 있고 default 값은 AUTO이다. 만약 쿼리를 실행할 때 flush()를 하지 않고 싶다면 해당 설정을 COMMIT으로 변경해서 적용하면 쿼리 실행시 flush()를 호출하지 않는다.
  • 트랜잭션이 종료되는 시점 (트랜잭션 커밋할 때)

@Modifying 이란?

주로 INSERT, UPDATE, DELETE 벌크 연산과 같이 사용되는 어노테이션이다. 

데이터를 대량으로 변경하는 경우에는 기존의 영속성 컨테이너에 캐시된 엔티디의 정합성이 깨질 가능성이 존재하기 때문에 @Modifying을 통해서 영속성 컨테이너를 다룬다.

 

  • flushAutomatically
    • entityManager가 flush()를 할 것인지 말 것인지를 설정하는 것
  • clearAutomatically
    • 쿼리 실행 후 1차 캐시를 clear()할 것인지를 설정하는 것

'spring > JPA' 카테고리의 다른 글

EntityManager와 EntityManagerFactory에 대해서  (0) 2023.11.15