OSIV Basics


OSIV?


OSIV: Open Session in View
Springでは、OSIV On状態のアプリケーションがデフォルトで実行されます.
OSIV Onの場合、API応答が終了するか、ビューはロードが完了するまで永続コンテキストとDBとの接続を維持します.
これまで、遅延ロード時に関連エンティティをインポートできた理由です.
遅延ロード関連エンティティをインポートするには、DBに接続を確立する必要があります.これは、開いている間にDBと接続を任意の場所で確立できるためです.

OSIV On or Off?


OSIVがオープン状態であれば開発の観点から非常に便利であるが,クローズ状態での開発が必要である.リアルタイム通信量が大きすぎてサービスが故障したためだ.
On状態の場合、APIリクエストまたはビューはDBへの接続を維持し続け、接続が不要な場合でもDBへの接続は維持されます.リアルタイム通信量が増加してDBへの接続がさらに必要になると、これらの接続が失われ、サービスが失敗する可能性があります.

OSIV Off


Off状態にするには、アプリケーションを使用します.ymlからspringへ.jpa.Open-in-view:falseに設定すればいいです.この場合、トランザクションが発生すると、永続性コンテキストとDBとの関係が維持され、トランザクションの終了時に接続プールに戻ります.これは、永続性コンテキストとDBへの接続が不要であれば、接続音の無駄を最小限に抑えることができることを意味する.
ただし、クローズ状態の場合は、トランザクション内で完了するために遅延ロードを開発し、関連エンティティをトランザクション外からJOIN FETCHにインポートする必要があります.

OSIV Off状態での開発


OSIV Off状態で開発する場合は,処理すべきロジックとコアビジネスロジックとAPIとビューを別々に開発することを提案する.

サービスでは、OrderServiceにはコアビジネスロジック、サービスが含まれています.Queryは他のAPIと一致するトランザクションロジックと必要なDTOを開発した.
(リアルタイムトラフィックの少ないサービスについては、OSVI On状態で開発しても問題ありません.)

API

	@GetMapping("api/v3_3/collection-orders")
    private Result ordersV3_3(@RequestParam(value = "offset", defaultValue = "0") int offset,
                              @RequestParam(value = "limit", defaultValue = "100") int limit) {
        // /api/v3_2/collection-orders?offset=1&limit=1
        List<OrderQueryServiceCollectionDTO> orderDTOS = orderQueryService.orderV3_2(offset, limit);

        return new Result(orderDTOS);
    }
V 3 3 3は、V 3 2と同じロジックを使用して、OSIV Off状態でも動作するように変更されます.V 3 2はorderItems導入時の遅延ロードであるため、再びDBに連絡する必要がある.OSIVの起動時はどこでもDBに接続できますが、シャットダウン時は対象内でしか行えず、V 3 2の運転時にエラーが発生します.

OrderQueryService

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderQueryService {

    private final OrderRepository orderRepository;

    public List<OrderQueryServiceCollectionDTO> orderV3_2(int offset, int limit) {
        List<Order> orders = orderRepository.findALlWithOrderMemberPaging(offset, limit); //ManyToOne, OneToOne 관계 모두 JOIN FETCH && Paging
        List<OrderQueryServiceCollectionDTO> orderDTOS = orders.stream()
                .map(o -> new OrderQueryServiceCollectionDTO(o))
                .collect(Collectors.toList());

        return orderDTOS;
    }

}

DTO

@Data
public class OrderQueryServiceCollectionDTO {
    private Long orderId;
    private String username; //주문자 이름
    private LocalDateTime orderDate;
    private OrderStatus orderStatus;
    private Address address; //배송지
    private List<OrderItemQueryServiceCollectionDTO> orderItems;

    public OrderQueryServiceCollectionDTO(Order order) {
        this.orderId = order.getId();
        this.username = order.getMember().getUsername();
        this.orderDate = order.getOrderDate();
        this.orderStatus = order.getStatus();
        this.address = order.getDelivery().getAddress();
        this.orderItems = order.getOrderItems().stream()
                .map((o) -> new OrderItemQueryServiceCollectionDTO(o))
                .collect(Collectors.toList());
    }
}
@Data
public class OrderItemQueryServiceCollectionDTO {
    private String itemName;
    private int orderPrice;
    private int count;

    public OrderItemQueryServiceCollectionDTO(OrderItem orderItem) {
        this.itemName = orderItem.getItem().getName();
        this.orderPrice = orderItem.getOrderPrice();
        this.count = orderItem.getCount();
    }
}
既存のOrderServiceとは異なり、@Transactional AlterationをOrderQueryServiceに追加してオブジェクトであることを通知します.これにより、永続性コンテキストとDBとの接続が形成される.