JPA에서의 Entity manager == Hibernate에서의 Session
즉, 사실상 JPA에서는 Open Entity Manager In View라고 생각하면 된다
JPA가 언제 DB Connection을 얻는가?
DB Transaction을 시작할 때 JPA persistence context가 connection 가져온다
JPA가 언제 DB Connection을 돌려주는가?
open-session-in-view가 켜져있는 경우
Service @Transactional 걸린 메소드를 벗어나도, client에게 값이 반환될 때까지 돌려주지 않는다
- view template의 경우 html과 data 모두 랜더링 후
- API의 경우 json으로 값이 client에게 tansfer된 후
지연 로딩 때문에 영속성 컨텍스트가 살아서 data를 가지고 올 수 있어야 한다
모든 작업이 끝난 후 connection 돌려주기 -> 영속성 컨텍스트 사라짐
open-session-in-view가 꺼져있는 경우
Sevice단에서 @Transactional 이 걸린 transaction이 끝나면
Controller 단으로 data 반환한 시점부터는
connection 돌려주고 영속성 컨텍스트 반환한다
Open-Session-In-View 의 단점
open-session-in-view ON 경우
오랜 시간 동안 connection을 가지고 있어서,
실시간 처리 application에서는 트래픽이 과부하걸릴 수 있다.
예시)
외부 API 연결하는데 외부 API 처리시간이 오래 걸린다면 내가 만든 Application도 해당 외부 API와의 DB connection 해제 못하고 다른 task들을 처리하지 못한다 -> Thread pool이 오버플로우 될 때까지 대기 또 대기..
open-session-in-view OFF 경우
connection 뿐만 아니라 영속성 컨텍스트도 반환되기 때문에
모든 지연로딩은 service - repository 단 즉, transaction 안에서 끝내버려야 함
-> controller와 view 단에서 지연로딩하면 안된다 즉, 철저하게 계층 분리 필요
설정하는 방법
application.yml
spring:
jpa:
open-in-view : true / false
OFF 인 상태에서 그럼 어떻게해..?
false 한 후에 transaction 외부에서 지연로딩을 한 경우
could no initialize proxy - no Session (LazyInitializeException) 이라는 에러를 만나게 된다
즉, session = db connection이 없어져서 proxy 객체에 접근했을 때, data를 가져올 수가 없다는 것이다
- fetch join 을 해서 proxy를 실제 entity로 채우거나 (사실상 지연로딩이 아님)
- transaction 안에서 지연로딩을 이미 다 끝내거나
따라서 open-in-view 가 false인 경우 위의 두가지 방법으로 controller 단에 가기 전에 미리 불러와야 한다
유지보수의 효용성을 위해 아래와 같이 service 단을 나누기도 함 (회사 레거시에 따라 다를 수 있음)
- 화면에 맞춘 Service - life cycle 빠름 (요구사항 변화에 따라 자주 변함)
- 핵심 비즈니스 로직에 맞춘 Service - life cycle 느림 (잘 변할 일이 없음)
서비스 특징에 따른 OSIV on/off
- 고객 서비스 기반 - api 트래픽이 많은 경우에는 off
- 회사 내부 서비스 기반 - admin 등 트래픽이 적은 경우 on
'Spring > JPA' 카테고리의 다른 글
[JPA] Entity가 아닌 DTO로 DB에서 data 가져오기 (0) | 2022.03.10 |
---|---|
[JPA] 1:N / N:1 상황에서의 N+1 문제 해결 (Fetch Join ~ 지연로딩/Batch Size) (0) | 2022.03.09 |
[JPA] Hibernate Batch Size 설정 (0) | 2022.03.09 |
[JPA] 준영속 엔티티를 변경하는 방법 - 변경 감지 / 병합(Merge) (0) | 2022.02.15 |
Spring Boot Repository EntityManager / EntityManagerFactory 엔티티매니저 / 엔티티매니저팩토리 (0) | 2021.12.27 |