← 질문 목록
#16깊이 0

@Transactional이 걸리지 않는 경우는?

프레임워크심화트랜잭션

프록시를 거치지 않고 메서드에 들어갔을 때다. 스프링의 트랜잭션코드가 아니라 프록시가 여는 것이다. 프록시를 통과하지 않으면 애초에 열릴 기회가 없다.

가장 흔한 자리가 자기 호출이다. 같은 클래스 안에서 this.method()로 부르면 그 호출은 프록시를 지나지 않고 실제 객체로 곧장 들어간다. 애너테이션은 붙어 있는데 아무 일도 일어나지 않는다. 로그도 예외도 없어서 원인을 찾기 어렵다.

  1. 1. 다른 빈에서 프록시로: 빈 참조로 부른다. **여기서 트랜잭션이 열린다**
  2. 2. 프록시에서 실제 객체로: 메서드 실행
  3. 3. 실제 객체에서 실제 객체로: this.method(). 프록시를 건너뛴다 — 안 걸린다

private 메서드도 같은 이유로 안 걸린다. CGLIB 프록시는 상속으로 만들어지는데 private은 재정의할 수 없다. final 메서드와 final 클래스도 마찬가지다.

주의

걸렸는데 안 되돌아가는 경우도 있다. 기본 롤백 대상은 unchecked 예외라, 체크 예외를 던지면 트랜잭션은 그대로 커밋된다. 되돌리려면 rollbackFor를 명시해야 한다.

자기 호출은 프록시를 거치지 않으므로 부가기능이 빠진다. 우회책을 아는 것보다 구조를 아는 쪽이 중요하다. 우회책은 대개 그 메서드를 다른 빈으로 꺼내는 것이고, 꺼내야 한다는 판단 자체가 구조 이해에서 나온다.

추천 꼬리질문

0/300

적은 내용은 AI 학습에 쓰일 수 있습니다. 이름이나 연락처는 넣지 말아 주세요.

관련 질문

@Transactional이 걸리지 않는 경우는?