
스프링과 JPA를 사용할 때 가장 중요한 전제는 DB 커넥션은 한정된 자원이라는 점임.
별도의 설정이 없다면 스프링은 Repository 메서드 단위로 세션을 관리함. 즉, 데이터 조회가 끝나면 즉시 커넥션을 반납하여 다른 요청이 사용할 수 있도록 함.
findById() 호출 시작 → 세션 오픈(Open) 및 DB 커넥션 점유.findById() 반환 → 세션 종료(Close) 및 커넥션 반납.기본 전략대로 세션이 즉시 닫히면, 연관된 데이터를 나중에 가져오려 할 때 문제가 발생함.
void test() {
Question q = repository.findById(1).get(); // 여기서 세션이 종료됨
q.getAnswerList().size(); // 세션이 이미 닫혀서 DB 접근 불가
}
@Transactional 어노테이션은 "이 메서드가 끝날 때까지 세션을 닫지 않는다."는 명령이라고 이해하면 됨.
findById()가 끝나도 트랜잭션 범위 안이라면 세션은 유지됨.getAnswerList() 등 추가적인 DB 접근이 가능해짐.모든 요청에 대해 세션을 길게 열어두면 편리하겠지만, 치명적인 단점이 있음.
따라서 스프링은 기본은 짧게, 꼭 필요한 곳(로직이 복잡한 곳)에만 @Transactional로 길게 가져가는 효율적인 방식을 가지고 있음.
베리베리스트로베리 귣잡