子方法异常时只对事务不回滚 [英] No rollback only for transaction when exception occurs in submethod

查看:14
本文介绍了子方法异常时只对事务不回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Hibernate + spring + @Transactional 注释来处理我的应用程序中的事务.

I'm using Hibernate + spring + @Transactional annotations to handle transactions in my application.

事务管理器声明如下:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

这在大多数情况下都很有效,但我发现了一个问题,我有 2 个方法,都注释了 @Transactional:

This works well in most cases, but I've found a problem where I have 2 methods, both annotated @Transactional:

package temp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

public class OuterTestService {
    @Autowired
    private InnerTestService innerTestService;

    @Transactional
    public void outerMethod() {
        try {
            innerTestService.innerTestMethod();
        } catch (RuntimeException e) {
            // some code here
        }
    }
}

package temp;

import org.springframework.transaction.annotation.Transactional;

public class InnerTestService {

    @Transactional
    public void innerTestMethod() throws RuntimeException {
        throw new RuntimeException();
    }
}

当我调用 OuterTestService#outerMethod() 时,出现异常

When I invoke OuterTestService#outerMethod(), I get an exception

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

由于只有一个事务(没有嵌套事务),整个outerTestMethod()的事务被标记为仅回滚.

As there is only one transaction (no nested transactions), the whole outerTestMethod()'s transaction is marked as rollback-only.

我发现我可以使用 noRollbackFor 轻松克服这个问题:

I've found that I can easily overcome this using noRollbackFor:

package cz.csas.pdb.be.service.tempdelete;

import org.springframework.transaction.annotation.Transactional;

public class InnerTestService {

    @Transactional(noRollbackFor = RuntimeException.class)
    public void innerTestMethod() throws RuntimeException {
        throw new RuntimeException();
    }
}

但这必须明确用于每个方法.因为在测试(回滚)期间不会引发此错误,所以这是不可接受的.

But this has to be explicitly used on every method. Because this error is not raised during tests (which are rollbacked), this is not acceptable.

我的问题——有没有办法自动(例如,不是针对每个方法)设置事务仅在启动事务的方法引发异常时回滚(在这种情况下,outerTestMethod())?

My question -- is there a way to automatically (eg. not explicitly for every method) set that transactions are rolled back only when an exception is raised from method which started the transaction (in this case, the outerTestMethod())?

推荐答案

创建另一个注释,例如@NoRollbackTransactional,类似于:

Create another annotation, e.g. @NoRollbackTransactional, something like:

@Transactional(noRollbackFor = RuntimeException.class)
public @interface NoRollbackTransactional {
}

并在您的方法中使用它.另一方面,我同意 Donal 的评论,您应该修改您的事务范围,恕我直言,从另一个 @Transactional 调用 @Transactional 通常不是一个好主意.

And use this on your methods. On the other hand I agree with Donal's comment, you should revise your transaction scopes, imho it is generally not a good idea to call @Transactional from another @Transactional.

这篇关于子方法异常时只对事务不回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆