@Transactional
쓰는이유?? 지연로딩
만약에 @ 트랜잭셔널 안쓰면 한줄씩 호출할때 DB connection을 열고 반납하고, 또 열고 반납함으로 리소스를 효율적으로 관리 할 수 있는데 @트랜잭셔널 사용시 계속 함수가 끝날때까지 열려 있으므로 리소스 치명적임
- 영속성 컨텍스트로 감시하는 비용
- DB connection을 연다(함수가 끝날 때까지 열려있다) -> 굉장히 치명적
- 조회하는 메서드에는
꼭 필요한지 먼저 판단하고
, 필요한 경우에만readOnly = true
로 달도록 한다
No → 만약에 연관관계가 있는 경우라면 지연로딩이 필요하기 때문에 이 경우엔 하나의 메소드라도 필요할 경우가 있다.
jpa 구현체에 모든 메서드는 @Transactional 선언이 되어 있다.
get (조회) 만 일어날 경우엔 필요 하지 않다.
save,put,delete 등의 상태변화가 일어날 경우엔 @Transactional 이 필요하다.
왜? → 예를 들어 save → get 이 일어날 경우엔 롤백이 필요할경우 save가 취소 되지만
save → delete 이 경우에 delete에서 취소가 될 경우 save 는 이미 처리 됐기 때문에 save도 반영되지 않을려면 롤백기능을 하는 @Transactional 이 필요하다.
엔테티가 영속성 컨텍스트에 관리되면 1차캐쉬부터 변경감지까지 얻을 수 있는 혜택이 많다. 하지만 영속성 컨텍스트는 변경 감지를 위해서 스냅샵 인스턴스를 보관하므로 더 많은 메모리를 사용하는 단점이 존재한다.
만약에 조회만 하는 경우에 읽기 전용으로 엔티티를 조회하면 메모리의 사용량을 최적화 할 수 있다.
스프링 프레임워크에서 제공하는 트랜잭션을 읽기전용 모드를 설정 할 수 있다.
@Transactional(readOnly = true)
트랜잭션에 readOnly=true 옵션을 주면 스프링프레임워크가 Hibernate의 Session Flush 모드를 MANUAL로 설정한다.
이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않는다.
따라서 트랜잭션을 커밋하더라도 영속성 컨텍스트가 플러시 되지 않아서 엔티티의 등록,수정, 삭제 등의 동작을 하지 않고, 또한 읽기 전용으로 , 영속성 컨텍스트는 변경감지에 대한 스냅샵을 보관하지 않으므로 성능이 향상된다.