OSIV가 왜 거기서 나와?

Kevin·2023년 7월 30일
0

JPA(Hibernate)

목록 보기
8/9
post-thumbnail

저번 글에서 짧게 이야기 했던 부분을 다시 이야기 해보기 위해서 먼저 코드를 보여주고, 궁금한 점을 이야기 해보겠다.


코드

UpdateMentoInfoHandler.class

@Component
@RequiredArgsConstructor
public class UpdateMentoInfoHandler {

    private final MentoService mentoService;
		
    public void execute(MentoInfoUpdateRequestDTO mentoInfoUpdateRequestDTO, Long Id) throws IOException {
        mentoService.updateMentoInfo(mentoInfoUpdateRequestDTO, mentoService.findMento(Id));
    }
}

MentoService.class

		@Transactional
    public void updateMentoInfo(MentoInfoUpdateRequestDTO updateRequest, Mento mento) {
        if (updateRequest.getIntroduction() != null) {
            mento.updateIntroduction(updateRequest.getIntroduction());
        }

        if (updateRequest.getCompany() != null) {
            mento.updateCompany(updateRequest.getCompany());
        }

        if (updateRequest.getMajor() != null) {

            Major.getMajor(updateRequest.getMajor().toString());

            mento.updateMajor(updateRequest.getMajor());
        }
    }


궁금한 점

저번 글에서 가지고 있던 궁금증이 해결되어서 즐거운 마음으로 있었으나, 또 다른 궁금증이 생겨서 부모 트랜잭션에 있는 @Transactional 어노테이션을 제거 해보았다.

나는 부모 트랜잭션을 제거하면, 같은 영속성 컨텍스트를 더 이상 공유하지 않기에 부모 메서드에서 영속성 컨텍스트에 저장했던 Mento 엔티티가 더 이상 Dirty Checking이 되지 않을 것이라고 생각했다…

그러나 여전히 Mento 엔티티가 Dirty Checking이 되는 것을 확인 할 수 있었다.

도대체 왜 Mento 엔티티가 Dirty Checking이 되는걸까?

답은 바로 OSIV였다.

그러면 OSIV가 뭐길래 이런 결과가 나왔는지 알아보자.



OSIV란?

내가 카카오 테크 캠퍼스에서 강사님께 배웠던 OSIV의 개념이란 다음과 같다.

💡 "Open in View"는 웹 애플리케이션에서 사용되는 개념으로, 데이터베이스의 트랜잭션을 뷰(View)가 렌더링되는 시점까지 연장하는 것을 의미한다. 이 개념은 주로 ORM(Object-RelationalMapping) 프레임워크에서 사용된다.

일반적으로 @Transactional이 붙은 레이어(서비스)에서 트랜잭션이 시작되고, 서비스가 종료될 때, 트랜잭션이 종료되며, 이것은 open in view를 false로 설정한 것과 동일하다.

"Open in View"를 사용하는 경우도 마찬가지로 트랜잭션의 시작은 서비스이고, 트랜잭션의 종료도 서비스가 종료될 때 종료된다.

하지만 DB에 select할 수 있는 세션이 view에 렌더링될 때까지 유지된다. 이 기능을 켜두고, 엔티티를 컨트롤러에서 응답하는 순간 Lazy Loading으로 인해 예상치 못한 결과가 발생할 수 있다.


그러면 OSIV 옵션을 켜고, 끌 때 각각의 특징에 대해서 살펴보자.


OSIV = true

  • OSIV = true → Select(DB 커넥션, 세션)가 처음부터(Controller부터) 가능하고, 데이터 수정, 추가, 삭제등은 Service부터 가능하다.
    • 쉽게 설명하면, select를 처음부터(Controller부터) 열어주는 것

OSIV = true의 장점

  • 그냥 DTO를 만들지 않고, 엔티티를 컨트롤러에서 리턴해도 LazyLoading이 가능하기에 상관 없어진다. → 혼자 개발할 때의 편의성이 증가한다.

OSIV = false

  • OSIV = false → 세션, 트랜잭션을 서비스가 끝나는 시점에 종료시킨다.
  • OSIV가 false 일 때 주의해야 할 점은 Service를 벗어나면 LazyLoading이 안되기 때문에 Service가 끝나는 시점에 엔티티를 DTO로 옮기면서 Lazy Loading을 처리 해 주어야 한다.

"Open in View"를 사용하는 경우 주의해야 할 점은 장기간 트랜잭션 유지로 인해 데이터베이스 리소스가 오랜 시간 동안 점유될 수 있으며, 불필요한 쿼리나 성능 문제가 발생할 수 있다. 따라서 "Open in View"를 사용할 때는 성능 측면과 리소스 관리에 유의하여 적절한 사용 방식을 선택해야한다



결론

Spring boot는 OSIV가 기본적으로 true로 켜져있고, 해당 OSIV를 false로 지정하면 더 이상 더티 체킹이 되지 않는 것을 확인할 수 있었다.

profile
Hello, World! \n

1개의 댓글

comment-user-thumbnail
2023년 7월 30일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

답글 달기