Spring @Transactional 2: TransactionInterceptor와 TransactionManager
TOC
Overview
파트 1에서는 @Transactional이 런타임에 Spring AOP 프록시와 TransactionInterceptor를 통해 동작한다는 점을 살펴봤다.
이번 글의 질문은 간단하다.
인터셉터는 실제 트랜잭션을 어떻게 시작하고 끝내는가?
인터셉터는 데이터베이스 API를 직접 호출하지 않는다. PlatformTransactionManager에 트랜잭션 처리를 위임한다.
클라이언트
→ AOP 프록시
→ TransactionInterceptor
→ PlatformTransactionManager
→ 트랜잭션 리소스
두 구성 요소의 역할
| 구성 요소 | 역할 |
| — | — |
| TransactionInterceptor | 메소드 호출 전후에 트랜잭션 경계를 적용한다. |
| PlatformTransactionManager | 트랜잭션 리소스를 시작·커밋·롤백한다. |
Spring은 사용하는 기술에 따라 매니저 구현체를 선택한다.
- JDBC:
DataSourceTransactionManager - JPA:
JpaTransactionManager - 여러 리소스: JTA 기반 매니저
구현체는 달라도 인터셉터가 매니저에 같은 추상화된 작업을 요청한다는 점은 같다.
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition);
void commit(TransactionStatus status);
void rollback(TransactionStatus status);
}
트랜잭션 실행 흐름
인터셉터의 동작을 단순화하면 다음과 같다.
// 실제 Spring 구현을 단순화한 의사 코드
public Object invoke(MethodInvocation invocation) throws Throwable {
TransactionStatus status =
transactionManager.getTransaction(transactionDefinition);
try {
Object result = invocation.proceed();
transactionManager.commit(status);
return result;
} catch (Throwable exception) {
if (rollbackOn(exception)) {
transactionManager.rollback(status);
} else {
transactionManager.commit(status);
}
throw exception;
}
}
호출 순서는 다음과 같다.
1. @Transactional 속성 확인
2. TransactionManager.getTransaction()
3. 원본 메소드 실행
4. 정상 반환이면 commit()
5. 롤백 대상 예외면 rollback()
6. 예외를 호출자에게 전달
invocation.proceed()가 프록시 다음에 있는 원본 객체의 메소드를 실행하는 부분이다.
TransactionManager가 하는 일
TransactionManager는 데이터 접근 기술에 맞는 트랜잭션 리소스를 준비한다.
- JDBC에서는 커넥션을 확보하고 트랜잭션을 시작한다.
- JPA에서는
EntityManager와 영속성 컨텍스트를 트랜잭션에 연결한다. - 기존 트랜잭션이 있으면 전파 속성에 따라 참여하거나 새로 시작한다.
이 리소스는 현재 실행 컨텍스트에 연결되므로 Repository나 Mapper가 매번 커넥션을 전달받지 않아도 같은 트랜잭션에 참여할 수 있다.
대상 메소드가 정상적으로 끝나면 매니저는 커밋을 수행하고, 롤백 대상 예외가 발생하면 변경 사항을 취소한다. 이후 커넥션이나 영속성 컨텍스트 같은 리소스를 정리한다.
Conclusion
@Transactional 실행에서 두 구성 요소의 책임은 명확히 나뉜다.
TransactionInterceptor는 트랜잭션 경계를 감싸고,PlatformTransactionManager는 실제 트랜잭션 리소스를 관리한다.