当子方法中发生异常时,仅事务不会回滚
我正在使用Hibernate + spring + @Transactional批注来处理我的应用程序中的事务。
事务管理器声明如下:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
在大多数情况下,此方法效果很好,但是我发现一个问题,我有2种方法,都标有@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由于只有一个事务(没有嵌套事务),因此整个outerTestMethod()事务都标记为“仅回滚”。
我发现可以使用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();
    }
}
但这必须在每种方法上明确使用。因为在测试(回滚)过程中不会引发此错误,所以这是不可接受的。
我的问题-
是否有一种方法可以自动(例如,不是为每个方法都明确地)设置事务仅在启动事务的方法(在本例中为outerTestMethod())中引发异常时才回滚?
回答:
创建另一个注释,例如@NoRollbackTransactional,例如:
@Transactional(noRollbackFor = RuntimeException.class)public @interface NoRollbackTransactional {
}
并在您的方法上使用它。另一方面,我同意Donal的评论,您应该修改您的交易范围,恕我直言,@Transactional与他人通话通常不是一个好主意@Transactional。
以上是 当子方法中发生异常时,仅事务不会回滚 的全部内容, 来源链接: utcz.com/qa/422382.html







