본문 바로가기
개발/Spring

[Spring] @Transactional 핵심 정리 / 우선순위, 프록시, 예외

by Allonsy 2022. 11. 26.
반응형

@Transactional 우선순위

1. 클래스의 메서드

2. 클래스의 타입

3. 인터페이스의 메서드

4. 인터페이스의 타입

-> 인터페이스에는 @Transactional을 쓰지 않는 것이 좋다(스프링5.0 이하에서 인식X, 다른 AOP 방식에서 적용 안 될 가능성)

 

@Transactional과 프록시

- @Transactional 애노테이션이 클래스나 메서드에 하나라도 있으면 트랜잭션 AOP는 프록시를 만들어서 스프링 컨테이너에 등록

 

- 동일 클래스 내에 @Transactional이 붙지 않은 메서드를 호출 후 @Transational이 붙은 메서드를 호출할 때 트랜잭션 적용 안됨

이유: @Transactional이 있는 클래스는 프록시가 만들어짐..

1) 프록시의 메서드(@Transactional X)을 호출 후

2) 내부 메서드(@Transactional O)를 호출할 경우

3) 프록시의 메서드가 아닌 프록시의 실제 클래스의 내부 메서드가 호출 됨

=> 이 메서드엔 트랜잭션 관련 코드 적용 안 되어 있음(프록시에 적용되어있음)

해결방법: 각각의 메서드마다 클래스를 따로 생성(프록시 각각 생성되서 프록시 객체 호출하게 됨, 트랜잭션 문제 없음!)

[트랜잭션 적용 안 되는 코드]

@Bean
public class A {

    public void noTx() {
    	tx(); // 내부 메서드 호출
    }

    @Transactional
    public void tx() {
    
    }
}

[클래스를 분리해서 트랜잭션 적용되는 코드 (빈 등록 코드 생략)]

@Bean
public class A {

    @Autowired B b; // bean 주입

    public void noTx() {
    	b.tx(); // 트랜잭션이 적용된 b클래스 프록시의 메서드 호출
    }

}

@Bean
public class B {

    @Transactional
    public void tx() {
    
    }
}

 

체크예외, 언체크예외 발생했을 때

체크예외 : 커밋

언체크예외(런타임예외) : 롤백

 

체크예외에도 롤백을 하고 싶을 경우엔 RollbackFor 옵션 사용

ex. @Transactional(rollbackFor = Exception.class)

반응형

댓글