我正在尝试在我的应用程序中使用一个声明性事务来进行多个数据库调用。我通过将@Transactional注释应用于相关方法来实现这一点,它看起来与此类似:
@Transactional
public MyReturnType myTransactionalMethod(SomeType1 param) {
SomeType2 someIntermediateObject = dao1.doStuff(param);
MyReturnType retObj = dao2.doMoreStuff(someIntermediateObject);
return retObj;
}
然后我在我的XML配置中设置了Spring Transactions:
<tx:annotation-driven transaction-manager="transactionManager" order="200"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
然后我想测试该方法以验证事务是否会在方法失败时正确回滚,所以我修改了我的方法看起来像这样:
public MyReturnType myTransactionalMethod(SomeType1 param) {
SomeType2 someIntermediateObject = dao1.doStuff(param);
MyReturnType retObj = dao2.doMoreStuff(someIntermediateObject);
throw new RuntimeException(); //The RuntimeException should trigger a rollback
}
当我执行第二种方法时,它没有像我期望的那样进行回滚,而是将创建的条目留在我的数据库中。我还期望在堆栈跟踪中看到一些弹簧方面的符号挂钩我的方法插入将处理事务的东西,但我只看到紧接在此事务方法之前的调用方法,没有任何Spring注入方法的迹象
任何人都可以看到我做错的任何会导致交易处理未应用的行为吗?
答案 0 :(得分:1)
此行为是因为您正在使用DataSourceTransactionManager,此txManager用于JDBC事务。例如,如果您在数据库中插入某些内容并且此操作失败,则会回滚此事务。如果您尝试插入超过允许值的值,则tx可能会失败。请注意,数据源知道失败。
在您的示例中,DataSource不知道失败,因为您正在抛出异常。对于这些情况,您可以使用JtaTransactionManager,但您的容器必须支持JTA事务。或者,您可以在数据库中尝试将某个值插入太长时间,或者在非空列中插入不同类型或空值的值。
你可以在这里看到更多:
http://www.journaldev.com/2603/spring-transaction-management-jdbc-example
http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html