🧐 : OSIV가 뭐야?
🧙 :
OSIV란 Open Session In View의 약자로
하이버네이트에선 Open Session In View
라고 표기하고
JPA에선 Open EntityManager In View
라고 표기하는데 그냥 OSIV라고 불러
Spring에서 표기할 때는 그냥 open in view 라고 쓰나봐!!
서버를 실행하면 콘솔창에
이렇게 WARNING이 뜨던게 하나 있었는데 warning의 원인을 보면 spring.jpa.open-in-view
가 보여!!
이게 뭐냐면 스프링과 DB의 커넥션과 관계가 있어
🧐 : 스프링은 언제 DB랑 커넥션이 일어나는데?
🧙 : 서비스 계층에서 트랜잭션이 시작될때!!
🧐 : 그럼 언제 DB에 값을 반환하는데?
🧙 :
open-in-view가 true냐 false냐 에 따라 달라!
open-in-view를 켜면(spring.jpa.open-in-view: true
) 트랜잭션이 끝나고 밖으로 나갈 때까지 반환을 안해.
이게 뭔소리냐면 트랜잭션은 리포지토리 안에서 시작되고 끝나는데 리포지토리 밖으로 나와도 DB 커넥션이 연결돼있다는거
왜 안하냐면 지연로딩은 프록시 객체를 쓴다는거고 프록시 객체는 영속성 컨텍스트가 살아있어야 쓸 수있어.
즉, open-in-view가 true 라는건 영속성 컨텍스트 & DB를 끝까지 살려둔다는 거지.
언제까지?? 렌더링 완성될 때까지. 그래서 지금까지 View Template이나 API 컨트롤러에서 지연로딩이 가능했던거야
🧐 : 오 그럼 좋은거아냐?
🧙 :
좋은것만은 아닌게
너무 오랫동안 DB 커넥션을 물고있어서 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄수도있고 이러면 장애로 이어져
뭐 다 trade off 임..
그래서 open-in-view 끄면(spring.jpa.open-in-view: false
) 트랜잭션 종료할 때 영속성 컨텍스트 닫고 디비 커넥션도 반환하기 때문에 커넥션 리소스 낭비안해
근데 끄면 모든 지연로딩을 트랜잭션 안에서 처리
해야돼
🧐 : 지연로딩을 트랜잭션 안에서 처리하는게 무슨뜻이야?
🧙 :
지금까지 지연로딩 최적화는 View Template이나 컨트롤러에서 처리했잖아
근데 트랜잭션 안에서 처리해야 한다는 의미는 리포지토리 단계에서 끝내야 된다는거야.
안끝나면 에러발생!
즉, 지금까지 사용한 방식은 못 쓴다는거지
🧐 : 그럼 지금까지 해논 지연로딩 최적화는 말짱 도루묵이네..
🧙 :
트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해 두면돼!!
🧐 : 어떻게??
🧙 :
해결방법은 처리하는 서비스를 따로 만들어서 관리하는거야(커맨드와 쿼리를 분리)
이런식으로 처리하면 해결!!
💡꿀팁💡
고객 서비스의 실시간 API는 OSIV를 끄고,
ADMIN 처럼 커넥션을 많이 사용하지 않는 곳에서는 OSIV를 켜놓자
이번 프로젝트에 admin 담당이어서 다행이다