其他分享
首页 > 其他分享> > 春季交易-防止未经检查的异常后发生回滚(RuntimeException)

春季交易-防止未经检查的异常后发生回滚(RuntimeException)

作者:互联网

我无法避免在RuntimeException之后阻止事务回滚.我的环境是在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并声明了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

解决方法:

据我所知,一旦从事务方法中抛出运行时异常并被事务拦截器拦截,则该事务将被标记为仅回滚.即使从另一个事务方法调用此事务方法.

这对我来说很有意义:如果内部方法无法从异常中恢复,则无法恢复,而外部方法则不应像没有任何反应那样进行.

如果您希望交易不会回滚,则可以

>使内部方法非事务性
>配置内部方法不回退此异常
>有两种内部方法:

>一种事务性的,旨在在尚无事务时调用,它仅委托给第二个事务
>非事务性的,旨在被称为现有事务的一部分

标签:spring-transactions,jta,hibernate,websphere,spring
来源: https://codeday.me/bug/20191028/1954748.html