使用AS400数据源的Spring Transactional:仅当数据源bean明确指定autocommit = false时,Rollback才有效

时间:2016-11-17 21:41:24

标签: java spring transactions db2

我有一个问题在过去几天一直困扰着我,我似乎无法弄明白。我已经看了很多关于它的问题,但似乎找不到适合我的问题。

情景

我有一个服务bean,其注释方法使用@Transactional(rollbackFor=DaoException.class)

此方法调用DAO,该DAO调用与DB2 AS400数据库交互的JdbcTemplate。我的配置xml看起来像这样:

<tx:annotation-driven proxy-target-class="true" transactionManager="txManager" />

<bean id="txManager" class="org.springframework.jdbc.core.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="dataSource" class="com.ibm.as400.access.AS400JDBCConnectionPoolDataSource">
    <property name=... value=... />
        ...
        ...
</bean>

<!-- Uses constructor injection to get dao -->
<bean id="service" class="com.my.package.service.MyService" />

<!-- Same, but for the JdbcTemplate -->
<bean id="dao" class="com.my.package.dao.MyDao" />

<bean id="template" class="org.springframework.blah.blah.JdbcTemplate">
    <property name="dataSource" ref="dataSource" />
</bean>

好的,所以当你查看日志时这一切似乎都有效。 TransactionManager注册,它在调用方法时打开一个事务,将JDBC连接设置为手动提交,然后声称在抛出异常时调用数据库上的回滚。

但是!事实并非如此。

DAO在我的数据库表上发出DELETE,删除了两行。然后应该发出INSERT来添加两个新行。我已经将代码更改为在删除后抛出所需的异常。这似乎引起txManager,但效果不存在......数据库中的行仍然缺失。

但是,如果我将<property name="autoCommit" value="false" />添加到dataSource bean,那么相同的过程实际上会起作用。数据保留在数据库中。这让我不确定我做对了。我很确定有旧的代码可能会受到关闭自动提交的影响...

我唯一能补充的是,在撰写本文时,我不确定@Transaction注释中的异常是否是未经检查的异常。我已经读过,检查过的异常不会导致回滚。但如果是这种情况,为什么日志看起来恰恰相反。我通过DataSourceTransaction管理器代码进行了调试,它也调用了它的回滚方法。

我的问题:

什么可能导致spring看起来像是按照日志进行回滚,但实际上并没有执行它。并且,当autoCommit设置为false时,为什么会发生回滚。

编辑:我将更新checked-vs-unchecked异常理论

0 个答案:

没有答案