Close
Close full mode
logo만렙 개발자 키우기

(1) 트랜잭션 범위와 영속성 컨텍스트

Git RepositoryEdit on Github
Last update: a year ago by nowwaterReading time: 2 min

스프링 컨테이너의 기본 전략

스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용.

  • 트랜잭션의 범위와 영속성 컨텍스트의 생존 범위가 같다.
  • 트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때 영속성 컨텍스트를 종료한다.
  • 같은 트랜잭션 안에서는 여러 위치(여러 레포지토리)의 엔티티 매니저를 사용해도 항상 같은 영속성 컨텍스트에 접근한다.

image

  • 다양한 위치에서 엔티티 매니저를 주입받아 사용해도 트랜잭션이 같으면 항상 같은 영속성 컨텍스트를 사용한다.

    예를 들면, Transaction 범위의 한 클래스에서 repo1 의 어떤 em.~~~() 수행하는 것과, repo2 의 em.~~!() 를 수행하는 것은
    둘 다 똑같은 영속성 컨텍스트를 사용하는 것.
  • 반면, 트랜잭션이 다르면 동일한 엔티티 매니저를 사용해도 다른 영속성 컨텍스트를 사용

image

  • Transaction 범위의 A 클래스, Transaction 범위의 B 클래스가 한 repo의 em.~~() 를 동시에 사용해도 트랜잭션에 따라 접근하는 컨텍스트가 다르다.

  • 즉, 스프링 컨테이너는 스레드마다 각각 다른 트랜잭션을 할당한다. -> 멀티 스레드 상황에 안전함


비즈니스 로직을 처리하는 서비스 계층에 @Transaction 어노테이션을 선언해서 트랜잭션을 시작한다.

어노테이션이 붙은 메소드를 실행하기 직전에 스프링의 트랜잭션 AOP가 먼저 동작한다.

트랜잭션 AOP

대상 메소드를 호출하기 전에 트랜잭션을 시작, 대상 메소드가 정상 종료되면 트랜잭션을 커밋하면서 종료

트랜잭션 커밋 시 영속성 컨텍스트 플러시 => 변경 내용 데이터베이스에 반영

예외 발생 시 트랜잭션을 롤백 -> 이때는 플러시 호출 X

@Controller
class HelloController {
@Autowired HelloService helloService;
public void hello(){
Member member = helloService.logic(); // 반환된 Member 엔티티는 준영속 상태
}
}
@Service
class HelloService {
@PersistenceContext
EntityManager em;
@Autowired Repository1 repository1;
@Autowired Repository2 repository2;
// 메소드를 호출할 때 트랜잭션을 먼저 시작
@Transactional
public void logic() {
repository1.hello();
// member는 영속상태 : 현재 트랜잭션 범위 안에 있으므로 영속성 컨텍스트의 관리를 받는다.
Member member = repository2.findMember();
return member;
}
// 트랜잭션 종료 : 트랜잭션 커밋, 영속성 컨텍스트 종료, 조회한 member는 이제부터 준영속 상태
}
@Repository
class Repository1 {
@PersistenceContext
EntityManager em;
public void hello(){
em.xxx(); // A 영속성 컨텍스트 접근
}
}
@Repository
class Repository2 {
@PersistenceContext
EntityManager em;
public void findMember(){
return em.find(Member.class, "id1"); // B 영속성 컨텍스트 접근
}
}

EntityManager는 다르지만 A와 B 모두 동일한 영속성 컨텍스트이다. => 동일한 트랜잭션 범위

이를 통해 컨테이너가 트랜잭션과 복잡한 멀티스레드 상황을 처리해줌으로써, 개발자는 싱글 스레드 애플리케이션처럼 단순하게 개발할 수 있고 비즈니스 로직 개발에 집중할 수 있다.

🚀 JPA — Previous
13장. 웹 애플리케이션과 영속성 관리
Next — 🚀 JPA
(2) 준영속 상태와 지연 로딩