2

我希望在事务块内执行少量插入查询,如果有任何错误,所有插入都将回滚。Spring事务管理器:回滚不起作用

我正在使用MySQL数据库和春季TransactionManager为此。 此外,表格类型为InnoDB

我已按照步骤here的步骤完成配置。

以下是我的代码(现在只有一个查询)

TransactionDefinition def = new DefaultTransactionDefinition(); 
TransactionStatus status = null; 

status = transactionManager.getTransaction(def); 
jdbcTemplate.execute(sqlInsertQuery); 
transactionManager.rollback(status); 

Spring配置XML:

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

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

数据源配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="${jdbc.driverClassName}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="username" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
    <property name="initialSize" value="${jdbc.initialSize}" /> 
    <property name="maxActive" value="${jdbc.maxActive}" /> 
    <property name="minIdle" value="${jdbc.minIdle}" /> 
    <property name="maxIdle" value="${jdbc.maxIdle}" /> 
    <property name="testOnBorrow" value="${jdbc.testOnBorrow}" /> 
    <property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> 
    <property name="testOnReturn" value="${jdbc.testOnReturn}" /> 
    <property name="validationQuery" value="${jdbc.validationQuery}" /> 
    <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" /> 
    <!--<property name="removeAbandoned" value="true"/> <property name="removeAbandonedTimeout" 
     value="10"/> <property name="logAbandoned" value="false"/> --> 
    <property name="numTestsPerEvictionRun" value="${jdbc.numTestsPerEvictionRun}" /> 
</bean> 

此代码工作完美罚款和记录被插入。 但回滚无效!它执行没有任何错误的回滚语句,但没有任何效果。

任何人都可以指导我,我哪里错了?

+0

你可以显示你的数据源配置吗? – fpmoles 2013-04-25 13:38:32

+0

@ Moles-JWS:我用数据源设置更新了我的问题。希望这可以帮助 – DarkKnightFan 2013-04-26 04:53:06

回答

3

看来问题是您的数据源没有设置为关闭自动提交。

<property name="defaultAutoCommit" value="false"/> 

试试看。我从来没有在代理之外使用过TransactionManager,所以我不确定是否有任何其他的问题直接使用它,但我建议你看看AOP事务或者AOP代理注释@Transactional,只是因为它更常见。

+0

感谢队友。这是行得通的。但如果你能在这里回答,我还有其他问题。我可以在java代码中处理这个问题,其中我明确地设置了autoCommit OFF,执行语句COMMIT/ROLLBACK,然后再次将autoCommit设置为ON。 – DarkKnightFan 2013-04-26 14:29:23

+0

当然你可以,只需从Spring的dataSource获得一个句柄,从它的连接中,你可以翻转AutoCommit位,执行代码,然后将其翻转并继续前进。我为什么要这样做而挣扎,但那只是我的观点而已。 – fpmoles 2013-04-26 15:27:06

+0

很高兴我可以帮忙,记得接受答案:) – fpmoles 2013-04-26 15:27:28

1

编辑:

我终于可以做来解决这个以下几点:

dmlDataSource.setDefaultAutoCommit(false); //set autocommit to false explicitly. 
Exception ex = (Exception)transactionTemplate.execute(new TransactionCallback() { 
       public Object doInTransaction(TransactionStatus ts) { 
        try { 
         dmlJdbcTemplate.execute(sqlInsertQuery); 
         ts.setRollbackOnly(); 
         dmlDataSource.setDefaultAutoCommit(true); // set autocommit back to true  
         return null; 
        } catch (Exception e) { 
         ts.setRollbackOnly(); 
         LOGGER.error(e); 
         dmlDataSource.setDefaultAutoCommit(true); // set autocommit back to true  
         return e; 
        } 
       } 
      }); 

我不使用事务管理器了。使用trasactionTemplate并执行以下操作:

Exception ex = (Exception)transactionTemplate.execute(new TransactionCallback() { 
       public Object doInTransaction(TransactionStatus ts) { 
        try { 
         dmlJdbcTemplate.execute(sqlInsertQuery); 
         ts.setRollbackOnly();       
         return null; 
        } catch (Exception e) { 
         ts.setRollbackOnly(); 
         LOGGER.error(e); 
         return e; 
        } 
       } 
      }); 

使用@痣,JWS的回答后,我现在能够成功回滚。但我只想用这种方法处理这个问题,而不是改变数据源的全局配置。

我可以在这里编程吗?

+1

我只是想,不会 dmlDataSource.setDefaultAutoCommit(false); 会影响您的全局数据源,并且在运行此部分时,每个模块的所有数据库事务都将自动提交设置为false。 – 2013-05-31 17:57:30

+1

嗯....你提出了一个好点@ShamimHafiz ...我将不得不测试一次...其他的替代方法是我创建了一个独立的jdbctemplate实例专门为这个功能。以便上述更改不会对其余代码产生任何影响。 – DarkKnightFan 2013-06-03 05:07:25