Post

[SPRNG] Transactional 어노테이션 선언과 Try-Catch 처리

[SPRNG] Transactional 어노테이션 선언과 Try-Catch 처리

[SPRNG] Transactional 어노테이션 선언과 Try-Catch 처리

@Transactional 선언과 try-catch 처리

  • Spring @Transactional어노테이션 롤백 처리 규칙
    • RuntimeException과 Error에 대해서 자동 롤백 실행
    • CheckedException에 대해서는 롤백하지않음(RollbackFor를 통해서 처리가능)

문제가 되는 경우

  • Transactional 어노테이션 선언 후에 try-catch를 해서 에러 처리를 하면 롤백이 작동하지 않음
  • 예외가 메소드 밖으로 전파되어야 Spring AOP가 이를 감지하고 트랜잭션을 롤백 처리
    • try-catch로 예외를 처리하면 전파가 차단되어 롤백이 작동하지 않음
1
2
3
4
5
6
7
8
9
10
11
@Transactional
public void someMethod(){
  try {
    // 데이타 베이스 작업
    insert("...");
    // 예외 발생
    throw new CSFWBizException("error");
  } catch (Exception e) {
    log.error("{}", ExceptionUtil.getErrorMessage(e));
  }
}

해결 방법

예외를 다시 던져서 처리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Transactional
public void someMethod(){
  try {
    // 데이타 베이스 작업
    insert("...");
    // 예외 발생
    throw new CSFWBizException("error");
  } catch (Exception e) {
    log.error("{}", ExceptionUtil.getErrorMessage(e));
    
    throw e;
    // 또는 throw new OtherException(e);
  }
}

명시적으로 롤백 마크

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Transactional
public void someMethod(){
  try {
    // 데이타 베이스 작업
    insert("...");
    // 예외 발생
    throw new CSFWBizException("error");
  } catch (Exception e) {
    log.error("{}", ExceptionUtil.getErrorMessage(e));
    
    // 명시적으로 롤백을 선언
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  }
}

특정 예외만 롤백하도록 설정

  • 일반적으로 프로젝트 내에서 선언하는 롤백방법
1
2
3
4
5
6
7
@Transactional(rollbackFor = Exception.class)
public void someMethod(){
  // 데이타 베이스 작업
  insert("...");
  // 예외 발생
  throw new CSFWBizException("error");
}
This post is licensed under CC BY 4.0 by the author.