본문 바로가기
Back-End/JPA

JPA) Spring OSIV

by 어렵다어려웡 2022. 3. 14.

스프링 OSIV

스프링 에서 제공하는 OSIV 는 ‘비즈니스 계층에서 트랜잭션을 사용하는 OSIV’ 이다.

말 그대로 비즈니스 계층에서만 트랜잭션을 사용하는 것이다.

 

 

동작원리는 다음과 같다.

  • 요청이 들어오면 서블릿필터 나 스프링 인터셉터 에서 영속성 컨텍스트를 생성한다.
  • Service 계층에서 트랜잭션을 시작할 때 생성되어 있던 영속성 컨텍스트를 찾아서 트랜잭션을 실행한다.
  • Service 계층 이 끝나면 트랜잭션을 커밋하고 Flush 한다.  이때 트랜잭션만 종료된다.
  • Controller , View 까지 영속성 컨텍스트가 유지되므로 조회된 엔티티는 영속상태를 유지한다.
  • 필터 나 인터셉터 로 요청이 돌아오면 영속성 컨텍스트를 종료한다, 이때 Flush 는 일어나지 않는다.

트랜잭션 없이 읽기

영속성 컨텍스트를 통한 모든 변경은 트랜잭션 안에서 이루어 져야한다.

트랜잭션 없이 엔티티를 변경하고 Flush 하면 예외가 발생한다.

 

엔티티를 변경하지 않고 단순히 조회만 할 때는 트랜잭션 없이도 가능한데 이것을 트랜잭션 없이 읽기 라고 한다.

프록시를 초기화하는 지연로딩도 조회 기능이므로 트랜잭션 없이 읽기가 가능하다.

스프링이 제공하는 OSIV 를 사용하면 Presentation 계층에서는 트랜잭션이 없으므로 엔티티를 수정할 수 없다.

따라서 기존의 OSIV 을 보완했다.

그리고 트랜잭션 없이 읽기를 사용해서 Presentation 계층에서 지연로딩 기능을 사용할 수 있다.

정리해보면 스프링이 제공하는 비즈니스 계층 트랜잭션 OSIV 는 다음과 같다.

  • 영속성 컨텍스트를 Presentation 계층까지 유지한다.
  • Presentation 계층은 트랜잭션이 없어 엔티티 수정 불가
  • Presentation 계층에서 트랜잭션이 없지만 트랜잭션 없이 읽기 기능을 통해 지연 로딩 이 가능하다.

스프링 OSIV 주의사항

스프링 OSIV 를쓰면 presentation 계층에서 엔티티를 수정해도 DB에 반영되지 않는데 한가지 예외가 있다.

presentation 계층에서 엔티티를 수정한 직후 트랜잭션을 시작하는 Service 계층을 호출하면 문제가 발생한다.

 

 

컨트롤러에서 엔티티를 수정하고 즉시 뷰를 호출 하는 게 아니라 트랜잭션이 동작하는 비즈니스 로직을 실행해서 이런 문제가 발생하는데, 해결하는 방법은 트랜잭션이 있는 비즈니스 로직을 모두 호출하고 나서 엔티티를 변경하면 된다.

1. 비즈니스 로직
2. Member member = memberService.getMember(id);
3. member.setName("XXX");

 

 

스프링 OSIV 는 같은 영속성 컨텍스트를 여러 트랜잭션이 공유할 수 있어서 이런 문제가 발생한다.

 

OSIV 를 사용하지않는 트랜잭션 범위의 영속성 컨텍스트 전략은 트랜잭션의 생명주기와 영속성 컨텍스트의 생명주기가 같으므로 이런 문제가 발생하지 않는다.

'Back-End > JPA' 카테고리의 다른 글

JPA) 벌크 연산  (0) 2022.03.30
JPA) Join Fetch, @EntityGraph 차이점  (0) 2022.03.24
JPA) 과거 방식의 OSIV  (0) 2022.03.13
JPA) 값 타입 컬렉션 vs @OneToMany  (0) 2022.03.12
JPA) 객체지향 쿼리  (0) 2022.03.12