복붙노트

[SPRING] Spring @ Transactional rollbackFor 작동하지 않습니다.

SPRING

Spring @ Transactional rollbackFor 작동하지 않습니다.

나는 아래 코드를 가지고있다.

   public abstract class AffltTransactionService implements IAffltTransactionService {
    ....

        @Override
        @Transactional
        public void processTransactions(List<? extends AffltTransaction> transactions) {
            for (AffltTransaction transaction : transactions) {
                if (transaction != null) {
                    processTransaction(transaction);
                }
            }
        }

        private void processTransaction(AffltTransaction transaction) {
            try {
                processTransactionInternal(transaction);

            } catch (Exception exception) {
                affltTransactionError = new AffltTransactionError(null, null, "error", new Date());
                saveAffltTransactionError(affltTransactionError);
                log.error(exception.getLocalizedMessage());
            }
        }

        @Transactional(readOnly=false, rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
        public void processTransactionInternal(AffltTransaction transaction) {

processTransactionInternal는 RuntimeException를 확장 한 ServiceUnAvailableException을 throw합니다.

그러나 rollbackFor = Exception.class가 있더라도 트랜잭션은 롤백되지 않습니다. 도와 주실 수 있습니까?

해결법

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

    1.@Transactional 어노테이션은 메소드를 직접 호출하는 경우 아무런 효과가 없습니다. 왜냐하면 Spring은 어노테이션이있는 클래스보다 상위에 프록시를 생성하고 aspect 정의 함수는 프록시에 의해 구현되기 때문입니다. 따라서, 클래스 내에서 메소드를 호출하면 프록시를 통과하지 못하므로 변환이 생성되거나 롤백되지 않습니다.

    @Transactional 어노테이션은 메소드를 직접 호출하는 경우 아무런 효과가 없습니다. 왜냐하면 Spring은 어노테이션이있는 클래스보다 상위에 프록시를 생성하고 aspect 정의 함수는 프록시에 의해 구현되기 때문입니다. 따라서, 클래스 내에서 메소드를 호출하면 프록시를 통과하지 못하므로 변환이 생성되거나 롤백되지 않습니다.

    자세한 설명은 Spring 레퍼런스를 보라.

  2. ==============================

    2.동일한 빈에서 다른 메소드로부터 하나의 메소드를 호출하기 때문에, Spring AOP는이 경우 어떠한 조언도 사용하지 않는다.

    동일한 빈에서 다른 메소드로부터 하나의 메소드를 호출하기 때문에, Spring AOP는이 경우 어떠한 조언도 사용하지 않는다.

    processTransactions 만 TransactionInteceptor로 랩핑됩니다.

    작동 시키려면 다음을 구성해야합니다.

    <aop:aspectj-autoproxy expose-proxy="true"/>
    

    그러나 그것은 권장되지 않습니다.

    더 많은 정보는 여기 : http://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy

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

    3.opensession 대신 getCurrentSession 사용

    opensession 대신 getCurrentSession 사용

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

    4.@Transactional을 적용하는 메소드는 예외를 throw해야합니다. 대신 try-catch를 사용하지 마십시오 (processTransaction 함수의 어딘가에서 try-catch를 사용하는 것 같습니다). 코드는 다음과 같아야합니다.

    @Transactional을 적용하는 메소드는 예외를 throw해야합니다. 대신 try-catch를 사용하지 마십시오 (processTransaction 함수의 어딘가에서 try-catch를 사용하는 것 같습니다). 코드는 다음과 같아야합니다.

    @Transactional
        public void processTransactions(List<? extends AffltTransaction> transactions) threws Exception{
            for (AffltTransaction transaction : transactions) {
                if (transaction != null) {
                    processTransaction(transaction);
                }
            }
        }
    
  5. from https://stackoverflow.com/questions/22957569/spring-transactional-rollbackfor-not-working by cc-by-sa and MIT license