Java/JPA

역속성 컨텍스트와 @Transactional

파란배개 2025. 1. 20. 12:51

@Transactional 어노테이션의 역할

@Transactional은 Spring에서 제공하는 어노테이션으로, 트랜잭션의 범위를 메서드 단위로 지정한다. 이 어노테이션을 사용하면 다음과 같은 이점이 있다:

  • 트랜잭션 자동 관리: 메서드 실행 시작 시 트랜잭션이 시작되고, 메서드가 정상적으로 종료되면 트랜잭션이 커밋된다. 예외가 발생하면 트랜잭션이 롤백된다.
  • 코드 간소화: 개발자가 직접 트랜잭션을 시작하고 커밋/롤백하는 코드를 작성할 필요가 없다.

JPA의 영속성 컨텍스트와 @Transactional

JPA는 영속성 컨텍스트를 통해 엔티티를 관리하며, 트랜잭션 범위 내에서만 유효하다. 주요 특징은 다음과 같다:

  • 엔티티의 상태 추적: 영속성 컨텍스트는 엔티티의 상태를 추적하고, 변경 사항을 데이터베이스에 반영한다.
  • 스냅샷 저장: 엔티티를 조회할 때, 영속성 컨텍스트는 엔티티의 상태를 복사한 스냅샷을 저장한다. 이는 변경 감지(Dirty Checking)에 사용된다.

코드 분석

코드 예제

@Transactional
public Article updateArticle(long articleId, String newAuthor, String newDescription) {
    // 1. 엔티티 조회
    Article article = articleRepository.findById(articleId).get();
    
    // 2. 엔티티 수정
    article.setAuthor(newAuthor);
    article.setDescription(newDescription);
    
    // 3. 엔티티 반환
    return article;
}

동작 과정

  1. 트랜잭션 시작:
    • @Transactional 어노테이션으로 인해 메서드 실행 시 트랜잭션이 시작된다.
    • 영속성 컨텍스트가 생성된다.
  2. 엔티티 조회:
    • postRepository.findById(id)를 통해 데이터베이스에서 Post 엔티티를 조회한다.
    • 조회된 엔티티는 영속성 컨텍스트에 저장되고, 스냅샷도 함께 저장된다.
  3. 엔티티 수정:
    • post.setAuthor(author)post.setDescription(description)를 통해 엔티티의 상태를 변경한다.
    • 영속성 컨텍스트는 엔티티의 변경 사항을 추적한다.
  4. 트랜잭션 커밋:
    • 메서드가 정상적으로 종료되면 트랜잭션이 커밋된다.
    • 영속성 컨텍스트는 엔티티와 스냅샷을 비교하여 변경 사항을 감지(Dirty Checking)하고, 데이터베이스에 UPDATE 쿼리를 실행한다.
  5. 트랜잭션 종료:
    • 트랜잭션이 종료되면 영속성 컨텍스트도 사라진다.

왜 메서드 내에서 직접 조회해야 하는가?

  • 영속성 컨텍스트의 관리 범위: 영속성 컨텍스트는 트랜잭션 범위 내에서만 동작한다. 따라서 메서드 내에서 직접 엔티티를 조회해야 영속성 컨텍스트가 엔티티를 관리할 수 있다.
  • 스냅샷과 변경 감지: 엔티티를 조회할 때 스냅샷이 저장되므로, 메서드 내에서 조회한 엔티티만 변경 감지가 가능하다. 외부에서 받아온 엔티티는 영속성 컨텍스트에 관리되지 않으므로 변경 사항이 감지되지 않는다.

외부에서 엔티티를 받아오는 경우의 문제

코드 예제

@Transactional
public void modify2(Post post, String author, String description) {
    post.setAutor(author);
    post.setDescription(description);
}

문제점

  • post 객체가 외부에서 전달되었기 때문에, 영속성 컨텍스트가 이 객체를 관리하지 않는다.
  • 따라서 변경 감지(Dirty Checking)가 동작하지 않아, 데이터베이스에 변경 사항이 반영되지 않는다.

Spring의 @Transactional과 JPA의 관계

  • JPA: 자카르타(Jakarta) EE의 표준 ORM 기술로, 영속성 컨텍스트와 엔티티를 관리한다.
  • Spring의 @Transactional: Spring 프레임워크에서 제공하는 트랜잭션 관리 기능이다. JPA와 함께 사용될 때, 트랜잭션 범위와 영속성 컨텍스트를 자동으로 관리한다.

정리

  1. @Transactional을 사용하면 트랜잭션 범위 내에서 영속성 컨텍스트가 동작한다.
  2. 메서드 내에서 직접 엔티티를 조회하고 수정해야 변경 감지가 동작한다.
  3. 외부에서 받아온 엔티티는 영속성 컨텍스트에 관리되지 않으므로 변경 사항이 반영되지 않는다.
  4. Spring의 @Transactional은 JPA와 함께 사용될 때 트랜잭션과 영속성 컨텍스트를 효율적으로 관리한다.