복붙노트

[SPRING] Spring 트랜잭션 - 검사되지 않은 예외 (RuntimeException) 이후의 롤백 방지

SPRING

Spring 트랜잭션 - 검사되지 않은 예외 (RuntimeException) 이후의 롤백 방지

RuntimeException 후에 트랜잭션이 롤백되지 않도록 관리 할 수 ​​없습니다. 내 env는 Websphere 8.0에서 실행되는 Spring 4.1 + Hibernate 3.6 + JTA (WebSphereUowTransactionManager)입니다.

우선, 예상대로 작동하는 간단한 사례입니다. RuntimeException을 잡아서 트랜잭션이 커밋되고 새 리소스가 성공적으로 만들어집니다.

@Service("fooService")
public class FooServiceImpl implements IFooService {

    @Transactional
    @Override
    public void doStuff(Resource res){
        authService.createResource(res, "ADMIN");
        try {
            throw new RuntimeException("SOMETHING");
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

다음은 괜찮습니다. noRollbackFor 선언하고 트랜잭션 커밋하자 :

    @Transactional(noRollbackFor=RuntimeException.class)
    @Override
    public void doStuff2(Resource res){
        authService.createResource(res, "ADMIN");
        throw new RuntimeException("SOMETHING");
    }

그리고 마침내 문제의 하나. 두 번째 차이점은 authService.createResource에 대한 두 번째 호출에서 예외가 발생한다는 것입니다. 참고로, authService.createResource는 @Transactional로만 표시되므로 기본 전파 구성이 적용되며 호출 서비스의 트랜잭션에 참여해야합니다.

    @Transactional(noRollbackFor=RuntimeException.class)
    @Override
    public void doStuff12(Resource res){

        authService.createResource(res, "ADMIN");
        try{
            res.setName("EXISTING-RESOURCE");
            authService.createResource(res, "ADMIN");
        }catch(RuntimeException e){
            e.printStackTrace();
        }
    }

RuntimeException을 catch하고 noRollbackFor 속성을 선언해도 트랜잭션은 항상 롤백됩니다. 어떤 설명 ??

로그 추적 정보 :

org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',+com.myorg.webapps.exception.ElementoYaExistente
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=false
org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Initializing transaction synchronization
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.test.service.impl.FooServiceImpl.doStuff12]
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource]
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Invoking WebSphere UOW action: type=1, join=true
org.springframework.transaction.interceptor.TransactionInterceptor TRACE - Getting transaction for [com.myorg.authmgr.service.impl.AuthorizationServiceImpl.createResource]
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Applying rules to determine whether transaction should rollback on java.lang.Runtime: Couldn't create the resource, it already exists: EXISTING-RESOURCE
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - Winning rollback rule is: null
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute TRACE - No relevant rollback rule found: applying default rules
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=true
org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCommit synchronization
org.springframework.transaction.jta.WebSphereUowTransactionManager TRACE - Triggering beforeCompletion synchronization
org.springframework.transaction.support.TransactionSynchronizationManager TRACE - Clearing transaction synchronization
org.springframework.transaction.jta.WebSphereUowTransactionManager DEBUG - Returned from WebSphere UOW action: type=1, join=false

해결법

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

    1.지금까지 내가 아는 한, 런타임 예외가 트랜잭션 메소드에서 발생하고 트랜잭션 인터셉터에 의해 인터셉트되자 마자 트랜잭션은 롤백으로 만 표시됩니다. 이 트랜잭션 메소드가 다른 트랜잭션 메소드에서 호출 된 경우에도 마찬가지입니다.

    지금까지 내가 아는 한, 런타임 예외가 트랜잭션 메소드에서 발생하고 트랜잭션 인터셉터에 의해 인터셉트되자 마자 트랜잭션은 롤백으로 만 표시됩니다. 이 트랜잭션 메소드가 다른 트랜잭션 메소드에서 호출 된 경우에도 마찬가지입니다.

    이것은 내게 의미가 있습니다. 내부 메소드가 예외에서 복구 할 수 없으면 복구 할 수 없으며 외부 메소드는 아무 일도 일어나지 않은 것처럼 처리하면 안됩니다.

    트랜잭션이 롤백되지 않기를 원한다면

  2. from https://stackoverflow.com/questions/28090428/spring-transactions-prevent-rollback-after-unchecked-exceptions-runtimeexcept by cc-by-sa and MIT license