【发布时间】:2011-05-23 12:13:49
【问题描述】:
我正在使用 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()) ?
【问题讨论】:
-
不确定你在期待什么,看看这个(但不认为这是个好主意)static.springsource.org/spring/docs/2.0.0/api/org/…
-
我希望能够配置事务管理器,使其在发生异常时不会回滚(或标记为仅回滚)事务,除非它发生在启动(或开始的原因)交易。
-
让
@Transactional方法调用另一个方法对我来说似乎是个坏消息,好像您并不清楚事务的范围是什么。我会先解决这个问题,不管怎样。 -
好吧,我需要在两者上都有@Transactional,因为每个都可以直接调用并且我需要它们在事务中。
标签: hibernate spring transactions rollback