본문 바로가기
Server/Spring

@Transactional 에 대하여

by Ahngyuho 2025. 2. 24.

오늘은 @transactional 애너테이션에 대해서 알아보려고 합니다. 

 

 

이 애너테이션을 알아보기 전에 일단 영속성 컨텍스트의 내부 구조 및 동작 흐름에 대해서 알아봅시다.

4, 5번이 이 애너테이션을 사용하는 이유입니다. 

 

  1. persist(엔티티) 를 실행하면 해당 엔티티 객체가 영속성 컨텍스트에서 관리되기 시작
  2. 1차 캐시라는 곳에 key 는 @ID 의 값, value는 해당 객체
  3. 바로 쿼리가 db 로 날아가는 것이 아니라, 해당 db 쿼리가 자동으로 만들어져서 쓰기 지연 저장소에 저장
  4. 트랜잭션 커밋이 실행되면 flush 라는 것이 실행되는데 이것은 쓰기 지연 저장소에 있는 쿼리를 DB 로 날려 변경 내용을 데이터베이스에 동기화하는 것
  5. 그리고 데이터베이스 커밋을 수행

- 4, 5 는 @Transactionl 이 붙은 메서드에서 자동으로 실행!


@Transactional이 실행되는 흐름

위의 createPost() 메서드가 실행될 때, 내부적으로 스프링 트랜잭션 관리자가 다음과 같은 작업을 수행합니다.

🔥 @Transactional이 적용된 메서드 실행 흐름

1. 메서드 실행 (트랜잭션 시작) - begin transaction; 
2. 엔티티 저장 (`postRepository.save(post)`) - INSERT SQL 실행되지 않고 **쓰기 지연 저장소**에 저장됨 
3. 메서드 정상 종료 (commit 수행) - `flush()` 실행 (쓰기 지연 저장소에 있던 SQL을 DB로 전송) 
- `commit()` 실행 (트랜잭션 완료, 변경 사항 확정) 

[예외 발생 시] - rollback 수행 (트랜잭션 롤백)

 

 


조금 더 구체적으로 이 애너테이션을 사용하면 어떤일이 일어나는지 적용된 기술과 함께 동작 흐름을 살펴보겠습니다.

 

게시글을 저장한다고 한다면 아래와 같은 코드를 작성할 수 있습니다. 

@Service
public class PostService {

    @Autowired
    private PostRepository postRepository;

    @Transactional
    public void createPost() {
        Post post = new Post();
        post.setTitle("New Post");

        postRepository.save(post); // 아직 DB에 SQL 실행되지 않음 (쓰기 지연 저장소에 있음)

        // 메서드 내부에서는 flush()와 commit()이 호출되지 않음!
    }
}

 

내부적으로 실행되는 과정

1. 클라이언트가 `createPost()` 호출
   - 실제 `PostService`가 아닌 프록시 객체(Proxy)를 호출
   - 프록시가 트랜잭션을 시작 (`begin transaction`)

2. 프록시가 `createPost()`를 실행
   - 엔티티를 저장 (`postRepository.save(post)`)
   - 쓰기 지연 저장소(hibernate ActionQueue)에 SQL이 모아짐 
   - 아직 DB에 쿼리가 실행되지 않음

3. `createPost()` 메서드 실행 완료 후, 프록시가 `flush()` 실행
   - 쓰기 지연 저장소의 SQL을 DB로 전송 (INSERT 실행)

4. 프록시가 `commit()` 실행
   - DB 변경 사항 확정

5. 예외 발생 시 `rollback()` 실행

 

@Transactionl 은 AOP 프록시 패턴을 사용하여 트랙잭션을 관리하는 기술입니다!

 

'Server > Spring' 카테고리의 다른 글

[Spring Cloud]  (0) 2025.03.04
[JPA] 영속성 컨텍스트  (0) 2025.02.24
HttpMessageConversionException 발생 원인과 해결책 알아보기  (0) 2023.08.12