SpringBoot & JPA API설계 - OSIV

Kim Dae Hyun·2021년 5월 17일
1

Spring-JPA

목록 보기
3/4
post-thumbnail

본 포스트는 김영한 님의 인프런 강좌를 수강 후에 정리한 내용입니다.

OSIV ?

OSIV (Open Session In View)

  • JPA에서 데이터베이스 커넥션과 영속성 컨텍스트의 생명주기를 관리하는 전략이다.
  • 기본값은 True로 아무런 설정을 하지 않는다면 OSIV 옵션은 켜져있는 상태이다.

OSIV ON

  • OSIV가 켜진 경우 API의 경우 Controller에서 사용자에게 값을 반환할 때까지 영속성 컨텍스트데이터베이스 커넥션유지한다.
    • JPA는 트랜잭션이 시작하는 시점에 데이터베이스 커넥션을 획득한다.
    • 보통 Service계층에서 @Transaction으로 트랜잭션을 시작하는 시점이다.
  • MVC의 경우 View에 랜더링되는 시점까지 영속성 컨텍스트는 데이터베이스 커넥션을 유지한다.
    • 그렇기 때문에 View단에서도 Lazy로딩이 가능한 것이다.
  • 이는 Lazy로딩이 Controller 혹은 View에서 가능한 이유이다.
    • 지금까지 API를 설계할 때 Lazy로딩을 통해 프록시 객체를 초기화하는 작업을 Controller에서 수행하였다. 빈 객체인 프록시 객체에 값을 할당 해야하는 것인데, 이 값을 어디서 가져와야 할까??
      • 영속성 컨텍스트.!
      • 영속성 컨텍스트가 Controller계층까지 유지 되어 Lazy로딩이 가능케 된 것이다.
    • 사용자에게 값을 반환하거나 View에 랜더링을 마친 후에 영속성 컨텍스트는 데이터베이스 커넥션을 반환하고 영속성 컨텍스트를 닫는다.
  • application.yml (OSIV설정)
    • default이므로 따로 설정해주지 않아도 된다.
  • 해당 옵션을 통해 Lazy로딩을 Controller계층에서 한 것은 이전 포스트에서 확인 가능하다.

OSIV OFF

  • open-in-view가 false인 경우 영속성 컨텍스트와 데이터베이스 커넥션의 생명주기는 트랜잭션의 생명주기와 동일하다.
    • 즉, 트랜잭션이 시작될 때 영속성 컨텍스트가 열리고 데이터베이스 커넥션을 획득한다.
    • 트랜잭션이 종료(함수가 종료)되는 시점에 영속성 컨텍스트는 닫히고 데이터베이스 커넥션은 반환된다.
  • 트랜잭션의 범위 밖에 있는 Controller나 View계층에서 영속성 컨텍스트를 이용하는 Lazy로딩이 불가능하다.
  • Lazy로딩이 실패한 모습
    • Lazy로딩을 Controller에서 수행한 코드
    • could not initialize proxy
      • 프록시 객체를 초기화할 수 없다 (=Lazy로딩을 할 수 없다)

ON? OFF?

  • OSIV전략을 사용하는 경우 Lazy로딩이 Controller와 View단에서 가능하다는 큰 장점이 있다.
    • 만약 Lazy로딩을 트랜잭션 내에서 모두 처리해야 한다면 생각보다 코드의 복잡도가 많이 올라가게 되고 유지보수 측면에서 좋지 않다.
    • 트래픽은 적은 경우, 커넥션 리소스를 감당할 수 있다면 OSIV전략을 사용하는 것이 절대 나쁜 것이 아니다.
  • OSIV전략을 사용하지 않는다면 데이터베이스 커넥션 리소스 낭비를 막을 수 있다.
    • 대량의 트래픽이 오가는 경우 OSIV전략을 사용한다면 커넥션 리소스가 마를 수 있다.
    • Controller에서 외부 API 호출 등에 의해 서비스가 잠시 Block된다고 해보자. 아직 사용자에게 응답한 것은 아니기 때문에 데이터베이스 커넥션을 물고 있는 상태이다. 낭비 낭비 낭비이다..
  • 결국 복잡성과 성능의 Trade-OFF ..
    • 트래픽 환경에 맞는 전략을 선택하자.
profile
좀 더 천천히 까먹기 위해 기록합니다. 🧐

0개의 댓글