영속성 컨텍스트?
엔티티를 영구 저장하는 환경으로 애플리케이션과 DB 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 DB에 바로 작업하지 않고 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
영속성 컨텍스트는 엔티티/@Id를 식별자 값으로 구분한다. 따라서 영속 상태는 식별자 값이 반드시 있어야 한다.
그리고 포인트는 flush 와 commit이 다르다는 것, flush는 DB에 적용은 하지만 최종 commit은 안 한 상태이다.
영속성에 대한 다른 내용들은 타 블로그에 잘 적혀있으니 참고 링크를 아래에 남기는걸로 대체하고, 보통 spring-data-jpa를 사용하기 때문에, spring 컨테이너의 기본 전략을 알아본다.
스프링 컨테이너의 기본 전략?
스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 말 그대로 트랜잭션의 범위와 영속성 컨텍스트의 생존 범위가 같다는 뜻인데, 즉 트랜잭션이 시작하는 순간 영속성 컨텍스트도 생성되고, 트랜잭션이 끝나는 순간에 영속성 컨텍스트가 종료되는 것이다.
우리는 보통 비즈니스 로직을 서비스에서 짜고, 함수에 @Transaction 어노테이션을 사용하여 트랜잭션을 시작한다.
내부적으로 보자면, @Transaction 이 있으면 호출한 메소드를 실행하기 직전에 스프링의 트랜잭션 AOP가 먼저 동작한다.
트랜잭션이 같으면 같은 영속성 컨텍스트를 사용한다.
즉, 위 그림과 같이 한 서비스에서 서로 다른 repository의 함수를 사용한다고 했을 때 각각의 entityManager는 다르지만 한 트랜젝션 내에서는 항상 같은 영속성 컨텍스트를 사용한다.
그리고 해당 영속성 컨텍스트는 트랜잭션과 생명주기가 똑같다.
그렇다면 위 그림처럼 컨트롤러나 뷰 같은 프리젠테이션 계층에서는? 준영속 상태가 된다.
준영속 상태는 영속 상태가 아니기 때문에 영속성 컨텍스트에서 제공하는 기능을 사용하지 못한다(지연로딩, 변경감지 등).
컨트롤러에서 업데이트를 하는건 아니라고 생각하여 변경 감지 기능이 굳이 필요하나 싶었는데, 지연로딩은 종종 컨트롤러에서 필요할 때가 있었던 기억이 있다..(1번 서비스로 어떤 엔티티를 구해온 후, 그 엔티티의 내용물을 2번 서비스로 넘길 때..)
영속성 컨텍스트를 뷰까지 살아있게...? 이 개념과 이어서 다음 시간에는 OSIV에 대해 살펴본다.
참고
영속성 컨텍스트: https://dev-monkey-dugi.tistory.com/72
준영속성과 지연로딩 등: https://www.nowwatersblog.com/jpa/ch13/13-2
transactional in read: https://willseungh0.tistory.com/75?category=880297
'개발 > spring' 카테고리의 다른 글
[actuator] git info를 health에 포함하기 (0) | 2022.01.28 |
---|---|
[jpa] OSIV란; spring.jpa.open-in-view (0) | 2022.01.27 |
[jpa] one-indexed pageable (0) | 2022.01.27 |
[swagger] in springboot2.6.2 and springdoc (0) | 2022.01.26 |
[gRPC] springboot2 gRPC server/client - clone coding (0) | 2022.01.20 |