나의 무지에서 오는 가벼운 의문이었다. @Transactional이 붙지 않은 메서드에서 영속성 컨텍스트는 어디까지 유지될까?
의문의 시작은 다음과 같다.
조회만 해오는 메서드에는 @Transactional을 붙이지 않았다. 붙일 이유가 없었기 때문이다. 그러다가 문득 조회만 해오는 메서드에서 생긴 영속성 컨텍스트가 어디까지 유지될 지 궁금해졌다.
메서드 끝까지? 컨트롤러 까지? 아무 생각 없이 실험해보기로 했다. 실험 환경은 아래와 같다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Team team;
...
}
@Service
public class TempService {
private final MemberRepository memberRepository;
public TempService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public Member findById(Long id) {
Member member = memberRepository.findById(id)
.orElseThrow(IllegalArgumentException::new);
member.getTeam();
return member;
}
}
TempService의 findById 메서드를 호출해보면 member.getTeam()에서 바로 LazyInitalizationException이 터진다. 디비를 찌를 동안에만 트랜잭션이 열리고 영속성 컨텍스트가 열리는 것 같다.
@Transactional을 안붙이니 한 메서드 안에서도 LazyInitalizationException이 터지는게 신기했다.
영속성 컨텍스트가 트랜잭션 범위에 따라 열리고 닫히고 한다는 것을 알고는 있었지만 트랜잭션이 없을 땐 어떻게 되는지 궁금했는데 해결이 됐다.
영속성 컨텍스트는 왜 트랜잭션 범위에 따라 열리고 닫힐까?
자세히는 검색해봐도 잘 안나온다. 많은 이유가 있겠지만 추측해보면 1차 캐시나 쓰기 지연 SQL 저장소의 데이터 불일치 방지나 DB와의 싱크 때문에 그럴 수 밖에 없을 것 같다.
생각해보면 여러 요청이 들어왔을 때 트랜잭션 범위에 영속성 컨텍스트가 있지 않다면 thread-safe 하지 않은 static 변수를 사용할 때의 문제점과 비슷하게 영속성 컨텍스트의 기능을 할 수가 없는 것 같다.
JPA를 더 많이 사용해보고 열심히 공부해야겠다. 😅
'삽질' 카테고리의 다른 글
Hibernate Envers 삭제 시 not null 에러 (0) | 2022.03.31 |
---|---|
몸체가 비어있는 무한 루프 (0) | 2020.10.19 |
Spring Data Jpa의 LazyInitializationException과 OSIV (0) | 2020.09.09 |
Reflection API와 JPA, Spring Bean (0) | 2020.07.22 |
JPA, EntityManager와 persist 관련 알게 된 사실 (0) | 2020.07.15 |