JPA 활용편 2 - API 개발 고급(실무 필수 최적화)

Stella·2022년 6월 24일
0

Java

목록 보기
17/18

API 개발 고급(실무 필수 최적화)

OSIV와 성능최적화

  • Open Session In View: hibernate
  • Open EntityManager In View: JPA

OSIV :ON

  • spring.jpa.open-in-view: true 기본값
  • OSIV 전략: 최초 데이터베이스 커넥션 시작(트랜잭션 시작)부터 트랜잭션이 끝나도 영속성 컨텍스트와 데이터베이스 커넥션을 유지
    • API 경우: API 응답이 반환될 때까지 DB커넥션 유지
    • View Template 경우: view template이 랜더링 완성되고 response 나갈때까지
      장점
  • lazy로딩은 영속성 컨텍스트가 살아있어야 가능
  • 영속성 컨텍스트는 db커넥션 유지 -> 영속성 컨텍스트의 생존범위가 확장(controller나 view에서도 사용가능)
    단점
  • 너무 오랫동안 db 커넥션을 유지하기 때문에 실시간 트래픽이 중요한 application에서는 db 커넥션이 모자랄 수 있음 -> 장애 유발

OSIV :OFF

  • spring.jpa.open-in-view: false
  • 트랙잭션이 끝나면 영속성 컨테스트도 닫고 db커넥션도 반환
    장점
  • db커넥션을 짧게 유지 -> 커넥션 리소스 낭비 하지않음, 커넥션 유연하게 사용가능
    단점
  • 모든 lazy 로딩 코드를 트랜잭션 안에 넣어야함
  • view template에서 지연로딩이 동작하지 않음
  • 트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해야함

커멘드와 쿼리 분리

  • OSIV를 끈 상태로 복잡성 관리 방법 -> Command와 Query를 분리
  • Controller에서 지연로딩을 써야할 때, Query용 Service를 따로 생성

API

@GetMappint("/api/v3/orders")
public List<OrderDto> ordersV3(){
	return orderQueryService.ordersV3();

OrderQueryService

@Transactional(readOnly = true)
public class OrderQueryService{
	public List<OrderDto> ordersV3(){
    	List<OrderDto> orders = orderRepository.findAllWithItem();
        
        List<OrderApiController.OrderDto> result = orders.strea().
        		.map(o -> new OrderApiController.OrderDto(o))
                .collect(toList());
        return result;    
  • OrderService
    • OrderService: 핵심 비즈니스 로직
    • OrderQueryService: 화면이나 API에 맞춘 서비스 (주로 읽기 전용 트랜잭션 사용)
  • 두 서비스 모두 트랜잭션을 유지하면서 지연 로딩을 사용 가능

고객 서비스의 실시간 API는 OSIV를 끄고, ADMIN 처럼 커넥션을 많이 사용하지 않는
곳에서는 OSIV를 켜는 걸 추천! (한 프로젝트라도 배포를 다르게 한다면)

profile
Hello!

0개의 댓글