当子方法中发生异常时,不会仅对事务进行回滚

问题描述

| 我正在使用Hibernate + spring +
@Transactional
注释来处理应用程序中的事务。 事务管理器声明如下:
<bean id=\"transactionManager\" class=\"org.springframework.orm.hibernate3.HibernateTransactionManager\">
    <property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>

<tx:annotation-driven transaction-manager=\"transactionManager\"/>
在大多数情况下,此方法效果很好,但是我发现有两个方法都带有@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()时,出现异常
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
因为只有一个事务(没有嵌套事务),所以整个ѭ5的事务都标记为仅回滚。 我发现可以使用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();
    }
}
但这必须在每种方法上明确使用。因为在测试(回滚)过程中不会引发此错误,所以这是不可接受的。 我的问题-是否有一种方法可以自动(例如,不是为每个方法都明确地)设置事务仅在启动事务的方法(在本例中为“ 5”)中引发异常时才回滚?     

解决方法

创建另一个注释,例如
@NoRollbackTransactional
,类似:
@Transactional(noRollbackFor = RuntimeException.class)
public @interface NoRollbackTransactional {
}
并在您的方法上使用它。另一方面,我同意Donal的评论,您应该修改交易范围,恕我直言,从另一个
@Transactional
调用
@Transactional
通常不是一个好主意。     ,您可能还需要关闭globalRollbackOnParticipationFailure。 当我在周围的交易中进行独立交易时,我遇到了这个问题。当独立事务失败时,它也使周围事务失败。 关闭参与标志为我解决了这个问题:
<bean id=\"transactionManager\" class=\"org.springframework.orm.hibernate3.HibernateTransactionManager\">
    <property name=\"globalRollbackOnParticipationFailure\" value=\"false\" />
    <property name=\"sessionFactory\" ref=\"sessionFactory\" />
</bean>
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...