@Transactional이란?
@Transactional은 Spring에서 제공하는 선언적 트랝개션 관리 방식으로, 메서드 실행을 하나의 트랜잭션으로 묶어주는 어노테이션이다.
예
@Transactional
public void createOrder() {
orderRepository.save(order);
paymentService.process();
}
이 경우 해당 메서드 내부의 작업은 하나의 트랜잭션으로 처리된다.
- 정상 실행 -> commit
- 예외 발생 -> rollback
@Transactional 동작 원리
Spring의 @Transactional은 AOP(Aspect Oriented Programming) 기반으로 동작한다.
핵심은 프록시(Proxy)이다.
1. 프록시 객체 생성
Spring 컨테이너는 @Transactional이 붙은 Bean을 발견하면 프록시 객체를 생성한다.
구조
Client -> Proxy -> Target Object
클라이언트는 실제 객체가 아니라 프록시 객체를 호출하게 된다.
2. 메서드 호출 가로채기
메서드 호출 시 프록시가 실행 흐름을 가로챈다.
흐름
메서드 호출 -> Proxy intercept -> 트랜잭션 시작 -> 실제 메서드 실행 -> commit/rollback
3. 트랜잭션 시작
프록시는 TransactionManager를 통해 트랜잭션을 시작한다.
Spring에서 사용하는 주요 트잭션 매니저
- DataSourceTransactionManager
- JpaTransactionManager
4. commit / rollback 처리
메서드 실행 후
- 정상 종료 -> commit
- RuntimeException 발생 -> rollback
예
start transaction -> business logic -> commit
또는
start transaction -> business logic -> exception -> rollback
@Transactional 동작 흐름 정리
Client -> Proxy -> TransactionManager -> DB Connection -> Business Logic
1. 프록시가 메서드 호출을 가로챔
2. 트랜잭션 시작
3. 실제 메서드 실행
4. commit 또는 rollback
@Transactional에서 자주 발생하는 문제
1. 같은 클래스 내부 호출
public void a() {
b();
}
@Transactional
public void b() {
}
이 경우 프록시를 거치지 않기 때문에 트랜잭션이 적용되지 않는다.
2. private 메서드
@Transactional
private void method() { ... }
프록시가 적용되지 않는다.