출처: https://blog.iroot.kr/341 [RootKR] 출처: https://blog.iroot.kr/341 [RootKR]

  OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어둔다는 뜻이다. 이렇게 되면 뷰에서도 지연 로딩을 사용할 수 있게 된다. 

 

과거 OSIV: 요청 당 트랜잭션

 요청 당 트랜잭션 방식의 OSIV는 클라이언트의 요청이 들어오자마자 서블릿 필터나 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 방식이다. 

 

요청 당 트랜잭션 방식의 OSIV 문제점

 문제는 컨트롤러나 뷰 같은 프리젠테이션 계층이 엔티티를 변경할 수 있다는 점이다. 

@RestController
@RequiredArgsConstructor
public class MemberController {
   private final MemberService memberService;
  
   public String viewMemberName(Long id) {
       Member member = memberService.findOne(id);
       member.setName("XXX");
      
       return member.getName();
   }
}

 위 코드의 의도는 고객 이름을 그냥 "XXX"로 뷰에만 노출하려는 의도였는데, 변경 감지로 인해 데이터베이스도 함께 변경돼버린 참사가 일어났다. (실제로 실무에서 이런 식으로 하는 작업했던 동료 덕에 많은 것을 배웠다...^^). 서비스 계층이 아닌 프리젠테이션 계층에서 데이터 변경은 유지보수하기 힘들어진다. 프리젠테이션에서 엔티티를 수정하지 못하게 막는 방법은 다음과 같다. 

  • 엔티티를 읽기 전용 인터페이스로 제공
  • 엔티티 레핑
  • DTO만 반환

 요즘은 위 문제들로 인해 트랜잭션 범위를 프리젠테이션 계층까지 열어두지 않는다. 스프링 프레임워크가 제공하는 OSIV는 위 문제를 보완해 비즈니스 계층에서만 트랜잭션을 유지하는 방식의 OSIV를 사용한다. 

(현업에선 Spring Boot를 사용하고 있는데, 스프링 부트는 OISV를 OpenEntityManagerInViewInterceptor로 기본으로 하고 있기 때문에 프리젠테이션까지 트랜잭션이 살아 있는 듯 하다.)

+ Recent posts