Transcational 과 Retryable 어노테이션을 같이 활용할 때는 순서를 따로 지정하지 않았으면, Retryable을 먼저 작성 후 Transcational을 작성해 주어야 한다.

제목은 트랜잭션과 리트라이블 이지만 Spring Ordered가 주 내용이다.

Spring Retry with Transactional

Transcational을 먼저 선언할 경우 Transcational이 먼저 시작되고, 이후 Retry가 되기 떄문에 RuntimeException 발생 이후 commit이 되지 않는다.

Transcational start
-> try logic 
-> throw RuntimeException
-> retry logic
-> Transcational End (Rollback)

이러한 방법을 해결하기 위해서 위에 말한 방법과 Orderd를 통해 어노테이션 순서를 적용하면 된다.

@Retryable(StaleStateException.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface CustomRetryable {}

트랜잭션 Rollback

트랜잭션이 RuntimeException이 발생하면 ThreadLocal에다가 롤백되었다고 상태를 저장한다. 하지만 그래서 궁금증은 트랜잭션이 끝난 이후에도 이 값을 그대로 유지하는지가 궁금했다.

디버그 모드로 트랜잭션을 추적해본 결과 transactionInfo에 null이 들어가는 것을 확인했다.

즉, 트랜잭션 안에 트랜잭션에서 RuntimeException이 발생했을 경우를 제외하고는 트랜잭션이 끝날 경우 rollback 되었다는 정보도 같이 초기화 된다.