스프링 JPA : Open Session In View

     

     

    Open Session In View : True

    Spring의 Open Session In View의 기본 설정값은 True다. 따라서 Open Session In View를 사용하는 것이다. 이것을 사용하게 되면 다음과 같은 현상이 발생한다.

    • 영속성 컨텍스트는 클라이언트의 요청이 들어오면 생성된다.
    • 트랜잭션은 @Transactional이 붙었을 때 실행된다.

    즉, 영속성 컨텍스트와 트랜잭션의 라이프 사이클이 다르다는 것이다. 

    상세 동작은 다음과 같다.

    1. 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스를 생성한다. 이 때 트랜잭션은 시작하지 않는다.
    2. 서비스 계층에서 @Transactional로 트랜잭션을 시작할 때 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아와서 트랜잭션을 시작한다.
    3. 서비스 계층이 끝나면 트랜잭션을 commit하고, 영속성 컨텍스트를 flush한다. 이 때, 트랜잭션은 끝내지만 영속성 컨텍스트는 유지된다.
    4. 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되기 때문에 조회된 엔티티는 영속 상태를 유지한다.
    5. 서블릿 필터, 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료한다. 이 때 플러시를 호출하지 않고 바로 종료한다.

     

    장점 : 트랜잭션 없이 읽기 → 어디서든 지연로딩이 가능. 

    • 영속성 컨텍스트는 트랜잭션 안에서 엔티티 조회, 수정이 가능하다.
    • 영속성 컨텍스트는 트랜잭션 바깥에서 엔티티 조회만 가능하다.

    Open Session In View 사용과 관련 없이 엔티티를 단순히 조회하는 것은 트랜잭션 없이 영속성 컨텍스트만 있으면 가능하다. 프록시를 초기화하는 지연로딩도 마찬가지로 엔티티를 단순히 조회하는 것이다. 따라서, 트랜잭션 없이 영속성 컨텍스트만 있으면 가능하다. 

     

    문제점1.

    영속성 컨텍스트는 요청이 나가기 전까지 살아있다. 즉, 조회된 엔티티는 영속성 컨텍스트에서 계속 관리되고 있다. 따라서 트랜잭션이 끝나서 영속성 컨텍스트에서 관리되고 있는 엔티티가 다시 한번 트랜잭션을 타게 되면 의도치 않게 변경이 될 수 있다. 

    1. 메서드A를 통해 컨트롤러는 A를 반환받는다.
    2. 컨트롤러에서 A값을 수정한다.
    3. 컨트롤러에서 B값을 받기 위한 메서드 B를 실행하며 트랜잭션2를 탄다.
    4. 트랜잭션 2에서 Tx.Commit()전 영속석 컨텍스트가 Flush 되는데 이 때, 영속성 컨텍스트에서 관리되고 있던 'A'에 변경감지가 확인되어 의도치않은 Update 쿼리가 나간다
    5. 'B'가 반환된다. 

    4번 스텝에서 의도치 않은 업데이트 쿼리가 나갈 수 밖에 없다. 이런 관점에서 OPEN SESSION IN VIEW를 처리하는 것은 문제점이 있다. 

    이에 대한 해결책은 DTO로 값을 반환받고, 컨트롤러 계층에서는 DTO를 튜닝하는 것이다. DTO는 엔티티가 아니기 때문에 영속성 컨텍스트가 관리하지 않는다. 따라서 다른 트랜잭션을 타더라도 의도치 않은 변경 쿼리가 나가지 않는다. 

     

    문제점2. 

    영속성 컨텍스트는 요청이 들어오고 나갈 때 까지 유지된다. 즉, 요청이 들어오고 나갈 때까지 DB와의 커넥션을 가진다. 여기서 큰 문제점이 발생할 수 있다. 만약 다음과 같은 상황이 있다고 가정해보자.

    1. 들어오는 요청이 엄청 많다.
    2. 들어오는 요청 대부분은 다른 서버의 API를 다시 한번 요청하고, 이 때 응답은 10초가 걸린다

    즉, 각 요청마다 다른 API에서 응답을 받는데 최소 10초를 대기해야한다. 하다못해 API 응답이 이상하다고 답이 올 때 까지 영속성 컨텍스트는 계속 유지된다. 이렇게 많은 요청이 계속 들어오게 되면 결국 DB 커넥션을 탈 수 있는 경우가 한계점에 도달한다. 즉, DB 연결이 마를 가능성이 생긴다.

    댓글

    Designed by JB FACTORY