Post

SpringBoot Open In View(OSIV) Default Enable

오늘 후배와 스프링에 대해 얘기하다 충격적인 얘기를 들었다. SpringBoot 의 spring.jpa.open-in-view (약칭 OSIV) 의 default 값이 true 라는 얘기이다.

해당 기능이 무엇인가 하면, spring 의 view 에서 db 커넥션을 얻을 시 view 요청이 종료 될 때 까지 DB Session 을 계속 유지 해 주는 기능이다. 이 기능이 켜져 있으면 transacion 이 종료 된 다음에도 jpa entity 의 lazy loading 이 가능하다. 하지만 db를 더이상 쓰지 않고 다른 작업을 하는중에도 커넥션을 풀에 돌려놓지 않고 계속 돌려놓고 있다는 퍼포먼스 쪽 이슈로 일반적으로 AntiPattern 으로 인식되고 있으며, 나는 관련 설정으로 인해 장애를 겪은 적도 있다.

장애가 어떤 케이스였냐면 아래와 같다

  1. DB 부하를 경감하기 위해 Replaction DB 를 준비하여 Readonly 로 세팅
  2. LazyConnectionDataSourceProxy 을 통해 @Transactionl readonly 세팅에 따라 서로 다른 IP로 연결
    1. 각각의 IP 는 Master / Slave-Readonly 로 세팅되어 있음
  3. 특정 페이지에서 2개의 Service 에 대해 함수 호출
    1. ServiceA 호출 -> 추가처리 -> ServiceB 호출 -> 리턴
    2. ServiceA 호출은 readonly. ServiceB는 아님
  4. 첫번째 Service에 의해 readonly connection 을 얻어 왔기 떄문에, OSIV 에 의해 connection 이 계속 유지되고 ServiceB 호출도 같은 커넥션으로 호출하게된다
  5. 하지만 readonly 로 설정된 db의 connection 이 었기 때문에 모든 write 가 실패한다

뭐 어쨋든 일반적으로 안좋은것으로 인식되는 기능의 default 가 true 상상하지 못한 기본값 설정에 대해 여러가지 조사를 하였고 확신은 못하지만 다음과 같은 결론을 낼 수 있었다.

  1. Hibernate가 처음 나왔을 당시에는 아직 연구가 되지 않아 편한 기능으로서 인식 되고 있었다
  2. Spring 은 어디까지나 첫 출시 당시는 Enterprise 를 타겟으로 하는 J2EE-EJB (현 Jakarta EE) 의 대체로 나온 프레임워크 였으므로 같은 DB를 여러대로 분산하는것은 일반적인 경우가 아니었다
  3. SpringBoot 는 출시 시점의 상황에 맞춰 기본값을 true 로 설정
  4. 시간이 지나고, OSVI 에 대한 부정적인 의견이 많아지고 분산환경이 흔해짐
  5. 하지만 새 버전에서도 하위호환성때문에 Default 값을 false 로 바꾸지는 않고, false 로 세팅 하지 않는 경우 Warn 로그를 띄움

이것까지 조사를 해 보고, 새 프로젝트 하나 생성해서 확인 해 보니 진짜 아래와 같은 로그가 남고 있었다. 다른 많은 Info 로그에 묻혀서 예전엔 눈치 채지 못했었다는걸 깨달았다

1
spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

결론은… 프로젝트 생성하자마자 일단 끄자 =_=

This post is licensed under CC BY 4.0 by the author.