들어가기 전
??? : 아름씨 서버가 응답을 안해주고 있는데요?
나 : 왜요...?
로그를 확인해보니 DB 커넥션 누수가 발생했고 집을 나간 커넥션들은 돌아올 생각을 안하고 있었습니다.
누수 포인트를 확인 해보니 SSE를 연결하는 API에서 사용자 정보를 DB에서 조회를 하기 위해 DB 커넥션을 사용한 뒤
SSE가 종료되기 전까지 커넥션을 유지하고 있어서 발생한 이슈였습니다.
왜 이런 이슈가 발생했을까요?
Open In View
Open-In-View는 관례상 OSIV(Open-Session-In-View)라고 하고, 경우에 따라 Open-EntityManager-In-View 라고도 합니다.
JPA에서 제공하는 기능 중 하나로 application.yml 설정 파일에서 Open-In-View를 true 혹은 false로 설정할 수 있습니다.
기본값은 true 입니다!
spring:
jpa:
open-in-view : true
true 인 경우
API라면 클라이언트에게 응답될 때까지,View라면 View가 렌더링될 때까지 영속성 컨텍스트가 살아있습니다.
저의 경우에는 SSE 연결이 해제가 되기 전까지 영속성 컨텍스트가 유지가 된 상황이었습니다.

false 인 경우
false일 경우에는 트랜잭션을 종료할 때 영속성 컨텍스트 또한 닫히게 됩니다.

controller에서 view에게 반환할 때 혹은 api 응답 값을 생성할 때 영속성 컨텍스트가 관리하는 객체에 접근할 수 없게 됩니다.
따라서 JPA 연관관계 매핑시 fetch type을 Lazy로 사용하게 된다면 controller에서 이 연관관계에 있는 객체를 호출 할 수 없습니다.
예를들어, Member와 Team이 1:N 관계로 연관관계를 맺고 있고 특정 사용자가 참여한 팀을 조회하려고 하였을 때,
Member정보를 가져올 땐 Team 의 정보는 지연로딩이므로 영속성 컨텍스트에 proxy 객체만 있고 실제 객체는 존재하지 않습니다.
여기서 Service 단의 일이 끝나고 Controller 단으로 가게 되면 영속성 컨텍스트는 닫히고 컨트롤러 단에서 팀 정보를 조회하려고 하는 경우 영속성 컨텍스트가 이미 닫혀있기 때문에 에러가 발생하게 됩니다!
즉, 영속성 컨텍스트가 닫혀있다면 Lazy Loading을 할 수 없습니다.
True 와 False 어떤 값으로 셋팅을 해야할까?
영속성 컨텍스트를 계속 유지하는게 당연히 🐶이득이지!
하지만 영속성 컨텍스트를 유지한다는 건, DB 커넥션을 계속 가지고 있다는 뜻이기 때문에 커넥션 풀을 10개로 제한을 뒀다고 하면 최악의 경우 동시 사용자 수가 10명인 서버가 될 수 있습니다.
실시간 트랙픽이 중요한 어플리케이션일 수록 DB 커넥션을 빠르게 회수하는게 중요하겠죠?
현재 상황을 고려해서 셋팅값을 설정하면 좋을 것 같아요.
마치며
개인적으론 이런게 있는걸 빨리 알았더라면 이 점을 염두해두고 코딩을 했을텐데 그렇게 하지 못한게 조금 아쉽습니다.
다음 프로젝트 혹은 리팩토링을 할 때는 이 점을 고려하여 작업을 해보려고 합니다.
긴 글 읽어주셔서 감사합니다!
🙇🏻 출처
https://gracelove91.tistory.com/100
https://velog.io/@dnwlsrla40/JPA-Open-In-View
'Dev > JPA' 카테고리의 다른 글
| 지연로딩(Lazy Loading) (0) | 2023.04.09 |
|---|