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;
}
동작 과정
- 트랜잭션 시작:
- @Transactional 어노테이션으로 인해 메서드 실행 시 트랜잭션이 시작된다.
- 영속성 컨텍스트가 생성된다.
- 엔티티 조회:
- postRepository.findById(id)를 통해 데이터베이스에서 Post 엔티티를 조회한다.
- 조회된 엔티티는 영속성 컨텍스트에 저장되고, 스냅샷도 함께 저장된다.
- 엔티티 수정:
- post.setAuthor(author)과 post.setDescription(description)를 통해 엔티티의 상태를 변경한다.
- 영속성 컨텍스트는 엔티티의 변경 사항을 추적한다.
- 트랜잭션 커밋:
- 메서드가 정상적으로 종료되면 트랜잭션이 커밋된다.
- 영속성 컨텍스트는 엔티티와 스냅샷을 비교하여 변경 사항을 감지(Dirty Checking)하고, 데이터베이스에 UPDATE 쿼리를 실행한다.
- 트랜잭션 종료:
- 트랜잭션이 종료되면 영속성 컨텍스트도 사라진다.
왜 메서드 내에서 직접 조회해야 하는가?
- 영속성 컨텍스트의 관리 범위: 영속성 컨텍스트는 트랜잭션 범위 내에서만 동작한다. 따라서 메서드 내에서 직접 엔티티를 조회해야 영속성 컨텍스트가 엔티티를 관리할 수 있다.
- 스냅샷과 변경 감지: 엔티티를 조회할 때 스냅샷이 저장되므로, 메서드 내에서 조회한 엔티티만 변경 감지가 가능하다. 외부에서 받아온 엔티티는 영속성 컨텍스트에 관리되지 않으므로 변경 사항이 감지되지 않는다.
외부에서 엔티티를 받아오는 경우의 문제
코드 예제
@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와 함께 사용될 때, 트랜잭션 범위와 영속성 컨텍스트를 자동으로 관리한다.
정리
- @Transactional을 사용하면 트랜잭션 범위 내에서 영속성 컨텍스트가 동작한다.
- 메서드 내에서 직접 엔티티를 조회하고 수정해야 변경 감지가 동작한다.
- 외부에서 받아온 엔티티는 영속성 컨텍스트에 관리되지 않으므로 변경 사항이 반영되지 않는다.
- Spring의 @Transactional은 JPA와 함께 사용될 때 트랜잭션과 영속성 컨텍스트를 효율적으로 관리한다.