JPA

13.3.2 스프링 OSIV : 비즈니스 계층 트랜잭션

fmoths 2021. 1. 29. 23:03

스프링 프레임 워크가 제공하는 OSIV는 비즈니스 계층에서 트랜잭션을 사용하는 OSIV다. 이름 그대로 OSIV를 사용하지만 트랜잭션은 비즈니스 계층에서만 사용한다는 뜻이다.

 

- 동작원리

- 클라이언트의 요청이 들어오면 영속성 컨텍스트를 생성한다. 이때 트랜젝션을 생성하지 않는다.

- 서비스 계층에서 트랜젝션을 시작하면 앞에서 생성해둔 영속성 컨텍스트에 트랜젝션을 시작한다.

- 비즈니스 로직을 실행하고 서비스 계층이 끝나면 트랜젝션을 커밋하면서 영속성 컨텍스트를 플러시한다.

- 이후 클라이언트의 요청이 끝날 때 영속성 컨텍스트를 종료한다.

 

1. 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스트를 생성한다. 단 이때 트랜잭션을 시작하지는 않는다.

2. 서비스 계층에서 @Transactional로 트랜잭션을 시작할 때 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아와서 트랜잭션을 시작한다.

3. 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 플러시 한다. 이때 트랜젝션은 끝나지만 영속성 컨텍스트는 종료하지 않는다.

4. 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지한다.

5. 서블릿 필터나, 스프링 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료한다. 이때 플러시를 호출하지 않고 바로 종료한다.

 

트랜젝션 없이 읽기

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

- 만약 트랜젝션 없이 엔티티를 변경하고 영속성 컨텍스트를 플러시 하면, 예외가 발생한다.

 

- 영속성 컨텍스트는 트랜젝션 범위 안에서 엔티티를 조회하고 수정할 수 있다.

- 영속성 컨텍스트는 트랜젝션 범위 밖에서 엔티티를 조회만 할 수 있다. 이것을 트랜젝션 없이 읽기라 한다.

- 프리젠테이션 계층에는 트랜젝션이 없지만 트랜젝션 없이 읽기를 사용해서 지연로딩을 할 수 있다.

 

스프링 OSIV 주의사항

class MemberController {

   public String viewMember(Long id) {
       Member member = memberService.getMember(id);
       member.setName("xxx") //보안상의 이유로 고객이름을 xxx로 변경했다.
       
       memberService.biz(); //비즈니스 로직
       return "view";
   }
}

class MemberService {

    @Transactional
    public void biz() {
       //비즈니스 로직 실행
    }
}

컨트롤러에서 엔티티를 수정하고 즉시 뷰를 호출한 것이 아니라 트랜젝션이 동작하는 비즈니스 로직을 호출하면 문제가 발생한다.