5. API 개발 고급 - 실무 필수 최적화

shin·2024년 5월 12일
post-thumbnail

1. OSIV와 성능 최적화

  • Open Session In View : 하이버네이트
  • Open EntityManager In View : JPA

1) OSIV ON

spring.jpa.open-in-view: true 기본값

  • 애플리케이션 시작 시점에 아래와 같은 warn 로그가 남음

    • open-in-view를 유의하여 사용해야한다는 것을 알려주는 문구
  • open-in-view 기본값을 뿌리면서 애플리케이션 시작 시점에 warn 로그를 남기는 것은 이유가 있음

  • 영속성 컨텍스트가 트랜잭션 시작 시점에 데이터베이스 커넥션을 가져옴

  • API가 유저에게 반환이 될때까지 데이터베이스 커넥션을 갖고 있음(더이상 필요가 없을때까지)

    • View HTML 렌더링이 완성되고 Response가 나가면, 그때 데이터베이스 커넥션을 돌려주고 영속성 컨텍스트까지 사라짐
  • OSIV 전략은 트랜잭션 시작처럼 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지함
  • open-in-view 옵션이 켜져있었기 때문에, 지금까지 View Template이나 API 컨트롤러에서 지연로딩이 가능했음

    • 지연로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지함 -> 장점
  • 그런데 이 전략의 치명적인 단점은 너무 오랜시간동안 데이터베이스 커넥션 리소스를 사용하기 때문에, 실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있음

    • 이는 결국 장애로 이어짐
    • 예를 들어 컨트롤러에서 외부 API를 호출하면 외부 API 대기시간만큼 커넥션 리소스를 반환하지 못하고 유지해야 함


2) OSIV OFF

spring.jpa.open-in-view: false OSIV 종료

  • OSIV를 끄면 트랜잭션을 종료할 때 영속성 컨텍스트를 닫고, 데이터베이스 커넥션도 반환함

    • 따라서 커넥션 리소스를 낭비하지 않음
  • 하지만 OSIV를 끄면 모든 지연로딩을 트랜잭션 안에서 처리해야함

    • 따라서 지금까지 작성한 많은 지연 로딩 코드를 트랜잭션 안으로 넣어야 하는 단점이 있음
    • view template에서 지연로딩이 동작하지 않음
    • 결론적으로 트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해 두어야 함

커멘드와 쿼리 분리

Command와 Query를 분리 : 실무에서 OSIV를 끈 상태로 복잡성을 관리하는 좋은 방법

  • 보통 비즈니스 로직은 특정 엔티티 몇 개를 등록하거나 수정하는 것이기 때문에 성능이 크게 문제가 되지 않음

  • 복잡한 화면을 출력하기 위한 쿼리는 화면에 맞추어 성능을 최적화하는 것이 중요함

    • 하지만 그 복잡성에 비해 핵심 비즈니스에 큰 영향을 주는 것은 아님

    • 그래서 크고 복잡한 애플리케이션을 개발한다면, 이 둘의 관심사를 명확하게 분리하는 선택은 유지보수 관점에서 충분히 의미 있음

    • OrderService : 핵심 비즈니스 로직

    • OrderQueryService : 화면이나 API에 맞춘 서비스(주로 읽기 전용 트랜잭션 사용)

      • 예시 코드
      @Transactional(readOnly = true)
      public class OrderQueryService {
        public List<OrderDto> orders() {
            // Order의 Controller 내부에서 처리하는 지연로딩 코드를 해당 서비스에서 처리
        }
  • 보통 서비스 계층에서 트랜잭션을 유지함

    • 두 서비스 모두 트랜잭션을 유지하면서 지연 로딩을 사용할 수 있음


정리

고객 서비스의 실시간 API는 OSIV를 끄고, ADMIN처럼 커넥션을 많이 사용하지 않는 곳에서 OSIV를 키는 것이 좋음



강의 : 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

profile
Backend development

0개의 댓글