我正在尝试在应用程序中的一个方法周围使用声明性事务,该方法会进行多次数据库调用。我通过将 @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 方面钩子(Hook)的一些迹象,这些钩子(Hook)将处理事务性内容,但我只看到紧接在该事务性方法之前的调用方法,没有任何 Spring 注入(inject)方法的迹象.
任何人都可以看到我做错了什么会导致未应用事务处理的行为吗?
最佳答案
此行为是因为您正在使用 DataSourceTransactionManager,此 txManager 用于 JDBC 事务。例如,如果您在数据库中插入某些内容并且失败,它将回滚该事务。如果您尝试插入的值超过允许的长度,则发送可能会失败。请注意,数据源已意识到该故障。
在您的示例中,数据源不知道失败,因为您抛出了异常。对于这些情况,您可以使用 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
关于java - Spring - 事务未在方法周围应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39477603/