복붙노트

[SPRING] try catch 블록을 사용할 때 Spring @ Transactional 주석

SPRING

try catch 블록을 사용할 때 Spring @ Transactional 주석

@Transactional 어노테이션으로 주석 된 메소드에서 예외를 catch하면 예외가 발생하면 롤백됩니까?

@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
public void yearEndProcess() {
    try {
        // try block
    } catch (Throwable throwable) {
        // catch block
    }
}

해결법

  1. ==============================

    1.예를 들면

    예를 들면

    class A{
    
        @Transactional
        public Result doStuff(){
            Result res = null;
            try {
              // do stuff 
            } catch (Exception e) {
    
            }
            return res ;
        }
    }
    

    doStuff 메소드에 예외가있는 경우, 트랜잭션은 롤백되지 않습니다.

    프로그래밍 방식으로 예외를 롤백하려면 다음과 같이 할 수 있습니다.

    선언적 접근법

    @Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
    public Result doStuff(){
       ...
    }
    

    프로그래밍 방식 롤백 TransactionAspectSupport에서 호출해야합니다.

    public Result doStuff(){
      try {
        // business logic...
      } catch (Exception ex) {
        // trigger rollback programmatically
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      }
    }
    
    You are strongly encouraged to use the `declarative approach` to `rollback` if at all possible. 
    `Programmatic rollback` is available should only be used if you absolutely need it.
    
  2. ==============================

    2.너는 이것을 읽고 싶을거야.

    너는 이것을 읽고 싶을거야.

    통합 트랜잭션 관리. @Transactional 어노테이션을 통해 또는 XML 구성 파일에서 트랜잭션 AOP advice를 명시 적으로 구성하여 선언적 AOP (aspect-oriented programming) 스타일의 메소드 인터셉터로 ORM 코드를 래핑 할 수있다. 두 경우 모두 트랜잭션 의미 및 예외 처리 (롤백 등)가 처리됩니다. 아래에 설명 된 것처럼 자원 및 트랜잭션 관리에서 ORM 관련 코드에 영향을주지 않으면 서 다양한 트랜잭션 관리자를 바꿀 수 있습니다. 예를 들어 두 시나리오에서 사용할 수있는 동일한 전체 서비스 (예 : 선언적 트랜잭션)를 사용하여 로컬 트랜잭션과 JTA간에 전환 할 수 있습니다. 또한 JDBC 관련 코드는 ORM을 수행하는 데 사용하는 코드와 트랜잭션 방식으로 완벽하게 통합 될 수 있습니다. 이는 일괄 처리 및 BLM 스트리밍과 같이 ORM에 적합하지 않은 데이터 액세스에 유용하며 ORM 작업과 공통된 트랜잭션을 공유해야합니다.

  3. ==============================

    3.봄 참고 문서에서

    봄 참고 문서에서

    Spring은 구체적인 클래스 (및 구체적인 클래스의 메소드)에만 주석을 달 것을 권장한다. @Transactional 어노테이션을 사용하여 인터페이스에 어노테이션을 작성하는 대신. 너는 분명히 할 수있다. @Transactional 어노테이션을 인터페이스 (또는 인터페이스 메소드)에 두지 만 이것이 효과적이다. 인터페이스 기반 프록시를 사용하는 경우에만 기대할 수 있습니다. 사실 자바 주석이 인터페이스에서 상속되지 않는다는 것은 클래스 기반 프록시를 사용하는 경우 (proxy-target-class = "true") 또는 위빙 기반 aspect (mode = "aspectj")이면, 프록시 설정 및 위빙 인프라에서 트랜잭션 설정을 인식하지 못하고 개체는 트랜잭션 프록시에서 래핑되지 않으며, 이는 분명히 좋지 않습니다.

    프록시 모드 (기본값)에서는 프록시를 통해 들어오는 외부 메서드 호출 만 도청. 즉, 자기 호출, 실제로는 대상 객체 내의 메소드 호출 대상 객체의 또 다른 메소드는 비록 런타임에도 실제 트랜잭션으로 이어지지 않습니다. 호출 된 메소드는 @Transactional로 표시됩니다.

    그런 다음 @Transaction에서 기본 동작은 RuntimeException이 롤백을 트리거하고, 확인 된 Exception이 롤백을 트리거하지 않는다는 것입니다. 그런 다음 트랜잭션이 모든 RuntimeException 롤백됩니다. 확인 된 Exception Throwable에 대해

  4. ==============================

    4.@Transactional 어노테이션에서 rollbackFor = Throwable.class 속성을 이미 언급했습니다.

    @Transactional 어노테이션에서 rollbackFor = Throwable.class 속성을 이미 언급했습니다.

    따라서 모든 종류의 예외 트랜잭션은 롤백됩니다.

  5. from https://stackoverflow.com/questions/25738883/spring-transactional-annotation-when-using-try-catch-block by cc-by-sa and MIT license