Open Session In View
application.yml의 spring.spa.open-in-view: ture -> 기본값
spring 기본 로직
트랜잭션 시작할 때 DB 커넥션 가져옴 -> 트랜잭션이 끝난 후에도 DB 커넥션을 가지고 있음
(osiv : true 인 경우)
why?
지연로딩일 때 실 엔티티 사용하기 위해서 영속성컨텍스트가 가지고 있는 객체를 사용해야 하기 때문.
OSIV란? >> 트랜잭이 시작 할 때 DB커넥션 가져와 시작 ~ API응답 끝날 때까지 영속성 컨텍스트에 DB 커넥션 유지 한 것
이로인해 너무 오래 DB 커넥션을 물고 있는 경우가 생긴다면 실시간 트래픽 사용할 때 장애가 발생할 수 있음
application.yml > spring.jap.open-in-view : false 설정
트랜잭션 끝나기 전에 지연로딩 로직 처리하자 ! == Controller는 영속성 컨텍스트에 포함
이때 잘못 사용하게 된다면 : org.hibernate.LazyInitializationException : could not initialize proxy 오류 발생
따라서
커멘드와 쿼리 분리할 것
Service : 핵심 비즈니스 로직 ( controller와 service관계일 때와 다름 없음 )
QueryService : API에 맞춘 서비스로 읽기전용 트랜잭션 (readonly=true)
단순 쿼리서비스 쪽 호출만 함.
@RestController
@RequiredArgsConstructor
public class OrderApiController {
//................
private final OrderQueryService orderQueryService;
@GetMapping("/api/v3/orders")
public List<OrderDto> orderV3() {
return orderQueryService.orderV3; // 단순 호출
}
//................
}
실제 API통신을 해줌
@RestController
@RequiredArgsConstructor
public class OrderApiController {
@GetMapping("/api/v1/orders")
public List<Order> ordersV1() {
List<Order> all = orderRepository.findAll(new OrderSearch());
// 지연 로딩을 시도한다.
for (Order order : all) {
order.getMember().getName();
order.getDelivery().getAddress();
List<OrderItem> orderItems = order.getOrderItems();
orderItems.forEach(o -> o.getItem().getName());
}
return all;
}
}
핵심 비즈니스 로직 처리
실시간 API사용량 많을 땐 OSIV : false !
커넥션 사용이 없을 땐 OSIV : true !