JPA에 대해서 헷갈렸던 개념들을 위주로 정리하는 글입니다.
OSIV
위의 모든 문제는 엔티티가 프레젠테이션 계층에서 준영속 상태이기 때문에 발생한다.
영속성 컨텍스트를 뷰까지 살아있게 열어두는 것을 OSIV라고 한다.
즉, OSIV란 영속성 컨텍스트를 뷰까지 열어둔다는 뜻이다.
과거의 OSIV: 요청 당 트랜잭션
요청이 들어오자마자 서블릿 필터나 스프링 인터셉터에서 영속성 컨텍스트를 만들면서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션과 영속성 컨텍스트를 함께 종료한다.
문제점
컨트롤러나 뷰 같은 프레젠테이션 계층이 엔티티를 변경할 수 있다는 점.
해결 방법
- 엔티티를 읽기 전용 인터페이스로 제공
- 엔티티 래핑
- DTO만 반환
스프링 OSIV: 비즈니스 계층 트랜잭션
과거의 OSIV는 요청 당 트랜잭션 방식의 OSIV로 문제점이 많아 최근에는 거의 사용하지 않는다. 최근에는 이런 문제점을 개선해서 비즈니스 계층에서만 트랜잭션을 유지하는 방식의 OSIV를 사용한다. 스프링 프레임워크가 제공하는 OSIV가 바로 이러한 방식을 사용한다.
동작 원리
1. 클라이언트의 요청이 들어오면 영속성 컨텍스트를 생성한다. 하지만 트랜잭션을 시작하지는 않는다.
2. 서비스 계층에서 트랜잭션을 시작하면 앞에서 생성해 둔 영속성 컨텍스트에 트랜잭션을 시작한다.
3. 비즈니스 로직을 실행하고 서비스 계층이 끝나면 트랜잭션을 커밋하면서 영속성 컨텍스트 플러시 한다. (트랜잭션만 종료하고 영속성 컨텍스트는 살려둔다.)
4. 클라이언트의 요청이 끝날 때 영속성 컨텍스트를 종료한다.
트랜잭션 없이 읽기
영속성 컨텍스트를 통한 모든 변경은 트랜잭션 안에서 이루어져야 한다.
만약 트랜잭션 없이 엔티티를 변경하고 플러시 하면 TransactionRequiredException 예외가 발생한다.
하지만 엔티티를 변경하지 않고 단순히 조회만 할 때는 트랜잭션이 없어도 되는데 이를 트랜잭션 없이 읽기라고 한다.
즉 정리하면...
영속성 컨텍스트는 트랜잭션 범위 안에서 엔티티를 조회하고 수정할 수 있다.
영속성 컨텍스트는 트랜잭션 범위 밖에서 엔티티를 조회만 할 수 있다. (트랜잭션 없이 읽기)
=> 프레젠테이션 계층에서는 트랜잭션이 없어 엔티티를 수정할 수 없다.
- (과거의 OSIV 문제 해결)
=> 프레젠테이션 계층에서는 트랜잭션 없이 읽기를 사용해서 지연 로딩 기능을 사용할 수 있다. (프록시 객체 초기화 가능)
- 엔티티가 준영속 상태여서 발생하는 문제 해결
'Application > JPA' 카테고리의 다른 글
[JPA] 1차 캐시 vs 2차 캐시 (1) | 2021.02.22 |
---|---|
[JPA] @Transaction(readOnly=true) 성능 향상 이유? (3) | 2021.02.22 |
[JPA] 트랜잭션 범위와 영속성 컨텍스트, Fascade 계층 (0) | 2021.02.22 |
[JPA] JPQL 객체지향 쿼리 심화 (0) | 2021.02.21 |
[JPA] 지연 로딩 N+1 문제와, JPQL 페치 조인 (0) | 2021.02.21 |