我希望在一个事务块中执行很少的插入查询,如果有任何错误,所有的插入将被回滚。
我使用MySQL
数据库和Spring TransactionManager。表类型为InnoDB
下面是我的代码(现在只有一个查询)
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>
这段代码工作得很好,记录被插入。但是回滚不起作用!执行回滚语句,没有任何错误,但没有任何效果。
谁能引导我哪里我错了?
问题似乎是您的数据源没有设置为自动提交关闭。
<property name="defaultAutoCommit" value="false"/>
试试吧。我从来没有在代理之外使用过TransactionManager,所以我不确定是否有其他像这样直接使用它的问题,但我建议你看看AOP事务或AOP代理注释@Transactional,因为它更常见。
EDIT:
我最终能够解决这个问题,通过执行以下操作:
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;
}
}
});
我现在没有使用事务管理器。使用transactiontemplate并执行以下操作:
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;
}
}
});
使用@ mole - jws的答案后,我现在能够成功回滚。但我只想在此方法中处理此问题,而不更改数据源的全局配置。
我可以在这里用程序来做吗?