트랜잭션 문제 해결 - 트랜잭션 템플릿
- 트랜잭션 매니저를 사용하면 서비스 계층이 특정 DB 접근 기술의 트랜잭션 처리 코드에 의존하지 않아도 되고 커넥션 동기화를 쉽게 이용할 수 있다.
- 트랜잭션 매니저의 한계
- 트랜잭션 매니저를 사용하더라도 트랜잭션을 시작하고, 비즈니스 로직을 수행하고, 성공하면 커밋하고, 실패하면 롤백하는 코드가 반복되는 문제가 있다.
- 바뀌는 건 비즈니스 로직 뿐인데 트랜잭션 처리 코드를 반복적으로 작성하는 건 피곤한 일이다.
- 템플릿 콜백 패턴
- 템플릿 콜백 패턴을 활용하면 반복되는 코드를 공통으로 처리하고 비즈니스 로직만 변경하여 코드를 작성할 수 있다.
- 스프링에서 TrasactionTemplate이라는 트랜잭션 공통 처리를 위한 템플릿 클래스를 제공하여 비즈니스 로직만 작성하면 되도록 해준다.
- TransactionTemplate의 한계
- TransactionTemplate을 활용해도 서비스 계층에 비즈니스 로직과 트랜잭션 처리 코드가 같이 존재하게 된다.
- 2가지 코드가 같이 존재하면 유지보수가 힘들어진다.
트랜잭션 문제 해결 - 트랜잭션 AOP 이해
- 스프링 트랜잭션 AOP를 사용해 프록시를 도입하면 서비스 계층에 순수 비즈니스 로직만 남기는 것이 가능한다.
@Transactional
을 사용하면 스프링 트랜잭션 AOP가 프록시를 자동으로 적용해준다.
org.springframework.transaction.annotation.Transactional

- 프록시를 도입하면 트랜잭션 처리 로직을 프록시가 모두 가져간다. 그리고 실제 비즈니스 로직을 프록시가 호출하는 방식으로 동작한다.
public class TransactionProxy {
private MemberService target;
public void logic() {
TransactionStatus status = transactionManager.getTransaction(..);
try {
target.logic();
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw new IllegalStateException(e);
}
}
}
public class Service {
public void logic() {
bizLogic(fromId, toId, money);
}
}
- 스프링 부트를 사용하면 트랜잭션 AOP 처리를 위해 필요한 다음의 클래스들을 스프링 컨테이너에 자동으로 등록한다.
- 어드바이저: BeanFactoryTransactionAttributeSourceAdvisor
- 포인트컷: TransactionAttributeSourcePointcut
- 어드바이스: TransactionInterceptor