Contents
see List작성일 2014. 09. 25.
Spring AOP와 트랜잭션 순서 설정하기
Spring에서 AOP(AspectJ)와 트랜잭션이 동시에 적용될 때 실행 순서를 제어하는 방법입니다. @Order 어노테이션과 Ordered 인터페이스를 활용합니다.
1. 문제 상황
로깅 AOP가 트랜잭션보다 먼저 실행되면 트랜잭션 밖에서 로깅되어 롤백 시 잘못된 로그가 남을 수 있습니다.
// 원하는 순서: 트랜잭션 시작 → 로깅 → 비즈니스 로직 → 로깅 → 트랜잭션 종료
// 잘못된 순서: 로깅 → 트랜잭션 시작 → 비즈니스 로직 → 트랜잭션 종료 → 로깅
2. @Order 어노테이션 사용
@Aspect
@Component
@Order(1) // 숫자가 낮을수록 먼저 실행 (외부)
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
log.info("메서드 시작: {}", pjp.getSignature());
Object result = pjp.proceed();
log.info("메서드 종료: {}", pjp.getSignature());
return result;
}
}
@Aspect
@Component
@Order(2) // LoggingAspect 다음에 실행 (내부)
public class SecurityAspect {
// ...
}
3. 트랜잭션 순서 설정
@Configuration
@EnableTransactionManagement(order = 0) // 가장 먼저 (가장 바깥)
public class TransactionConfig {
// ...
}
// 또는 XML 설정
<tx:annotation-driven order="0"/>
4. 실행 순서 예시
// Order 값: 트랜잭션(0) → 로깅(1) → 보안(2)
트랜잭션 시작 ─┐
로깅 시작 ─┤
보안 체크 ─┤
비즈니스 로직
보안 체크 ─┘
로깅 종료 ─┘
트랜잭션 커밋 ─┘
5. Ordered 인터페이스 구현
@Aspect
@Component
public class LoggingAspect implements Ordered {
@Override
public int getOrder() {
return 1;
}
// ...
}
6. 실전 권장 순서
| Order | Aspect | 용도 |
|---|---|---|
| 0 | Transaction | 트랜잭션 관리 (가장 외부) |
| 1 | Logging | 메서드 진입/종료 로깅 |
| 2 | Security | 권한 검사 |
| 3 | Validation | 입력값 검증 |
| 4 | Caching | 캐시 처리 |
7. 주의사항
- Order 값이 같으면 실행 순서 보장 안 됨
- @Order는 Spring Bean에만 적용
- Lowest값(Integer.MAX_VALUE)이 가장 마지막 실행
- Aspect끼리만 순서 조절, 일반 빈은 별도
8. 디버깅 팁
// 현재 적용된 AOP 순서 확인
@Autowired
private AspectJProxyFactory factory;
// 로그 레벨 설정
logging.level.org.springframework.aop=DEBUG
logging.level.org.springframework.transaction=DEBUGspring
| No | 작성일 | Title |
|---|---|---|
| 2005 | 2025. 11. 30. | Spring Security 6 JWT 인증 구현 |
| 2004 | 2025. 11. 30. | Spring Boot 3.x 새로운 기능 정리 |
| 1824 | 2022. 05. 24. | [ spring ] interceptor 등 스프링에서 @Autowired 인식을 못할때 |
| 421 | 2016. 08. 02. | [ spring-security ] 스프링 시큐리티 csrf (크로스도메인) 설정방법 |
| 349 | 2016. 02. 16. | [ spring ] spring4 jsonp callback |
| 346 | 2016. 02. 08. | [ spring 4 ] 스프링 4 websocket 및 stomp (채팅 및 쪽지 구현) |
| 344 | 2016. 02. 06. | [ spring-security ] 스프링 시큐리티 4 버전에서 hasRole 및 hasAnyRole 안될경우 |
| 328 | 2015. 11. 05. | [ spring security ] 스프링 시큐리티 유저정보 얻는 방법 |
| 311 | 2015. 06. 30. | [ spring ] IOException while loading persisted sessions: java.io.EOFException 해결 |
| 310 | 2015. 06. 29. | [ spring ] How To Get HTTP Request Header In spring ( 스프링에서 http header 값 가져오기) |