
@Transaction의 전파
트랜잭션 안에 또 다른 트랜잭션이 있거나 관리해야 할 때
@Transaction 안에 propagation 옵션을 통해 전략을 선언하여
전파의 범위를 설정할 수 있다
그 전에 부모-자식 관계의 트랜잭션이 뭔지 조금 정리하자
@Transactional // 부모 트랜잭션
public void parentMethod() {
// ...
childMethod(); // 자식 트랜잭션
}
@Transactional // 자식 트랜잭션
public void childMethod() {
// ...
}
// 부모 트랜잭션이 있는 상태에서 자식 트랜잭션을 호출 한 것다만 유의 할 점은 같은 클래스 내라면 전파가 되지 않는다
이유는 스프링의 @Transactional 은 AOP 로 만들어졌는데
이 AOP의 동작이 내부 호출은 프록시를 거치지 않기 때문이다
프록시를 거쳐야 전파가 된다
전파의 종류
이전에 알고 있어야할 어노테이션 - 3에서 정리 했지만 좀 더 자세히 정리하였다
REQUIRED (기본값)
부모 트랜잭션이 있으면 그 트랜잭션에 참여
부모 트랜잭션이 없으면 새 트랜잭션 생성
REQUIRED_NEW
무조건 새 트랜잭션 생성
핵심 기능의 성공 여부와 상관 없이, 반드시 기록되어야 하는 부가 기능에 사용
에러 로그, 행동 로그 등등
게시글 작성 + 알람에서 알림 발송의 경우에 사용 (실패해도 게시글은 저장)
NESTED
부모 트랜잭션이 있으면 그 안에 중첩 트랜잭션을 만듬 (savepoint 개념)
부모 트랜잭션이 없으면 새 트랜잭션을 만듬
이 중첩된 트랜잭션은 개별로 롤백 처리가 가능함
부모 트랜잭션이 롤백되면 같이 롤백처리하나의 큰 작업 중 실패할 가능성이
있는 부분을 따로 분리하여 예외처리 할 때 사용
(상품 주문 처리 중 여러개의 쿠폰의 사용 → 이 중 하나가 실패하더라도?
주문을 처리되어야하는 이런 상황에 사용)
SUPPORTS
부모 트랜잭션이 있으면 참여
부모 트랜잭션이 없으면 그냥 실행됨
주로 Read-Only 메서드에 활용
트랜잭션이 있든 없든 로직 수행에 문제가 없을 때 사용
MANDATORY
부모 트랜잭션이 있어야만 작동하게 함
없으면 IllegalTransactionStateException 예외 발생
NEVER
트랜잭션이 없어야만 실행됨
참여하게 할 경우 IllegalTransactionStateException 발생