我在我的应用程序中使用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
}
}
}
and
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()
)引发异常时回滚的方式(例如,不显式为每种方法设置)?
@Transactional
方法中调用另一个方法似乎对我来说不是好消息,就好像你并不真正清楚事务的范围是什么。我会先解决这个问题,无论如何。 - Donal Fellows