问题描述
全部,我遇到了使用 Spring Batch CompositeItemWriter 的事务回滚问题.Spring批处理的版本是2.2.7.
All, I am experiencing a transaction roll back issue using Spring Batch CompositeItemWriter. The version of Spring batch is 2.2.7.
我的配置与此处的帖子相同:https://stackoverflow.com/questions/32432519/compositeitemwriter-doesnt-roll-back-in-spring-batch
My configuration is identical to a post here : https://stackoverflow.com/questions/32432519/compositeitemwriter-doesnt-roll-back-in-spring-batch
<bean id="compositeItemWriter" class="org.springframework.batch.item.support.CompositeItemWriter">
<property name="delegates">
<list>
<ref bean="firstItemWriter"/>
<ref bean="secondItemWriter"/>
<ref bean="thirdItemWriter"/>
</list>
</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="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
</bean>
当第三项写入器抛出异常时,之前写入器写入数据库的数据不会回滚.
When there's an exception thrown at thirdItemWriter, data wrote to database by previous writers are not rolling back.
不确定我遗漏了什么,但我的理解是复合项目编写者共享相同的事务,如果发生异常,所有数据都应该回滚.
Not sure what I am missing, but my understanding is the composite item writers share the same transaction, all data should be rolled back in the event of exception.
感谢任何建议
推荐答案
经过几天的工作,终于有了解决方案.关键是将所有写入者放在一个事务中并关闭自动提交.
After few days worth of work on this, finally come with a solution. The key is put all writers in one transaction and turn off auto commit.
public class TransactionAwareCompositeItemWritter<T> extends CompositeItemWriter<T> {
private static Logger LOG = LoggerFactory.getLogger(TransactionAwareCompositeItemWritter.class);
private List<ItemWriter<? super T>> delegates;
private PlatformTransactionManager transactionManager;
private JdbcTemplate jdbcTemplate;
@Override
public void write(final List<? extends T> item) throws Exception {
Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
if (con.getAutoCommit()) {
LOG.debug("Switching JDBC Connection [" + con + "] to manual commit");
con.setAutoCommit(false);
}
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("CompositeItemWriter Transaction");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
for (ItemWriter<? super T> writer : delegates) {
writer.write(item);
}
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
transactionManager.commit(status);
if (!con.getAutoCommit()) {
LOG.debug("Switching JDBC Connection [" + con + "] to auto commit");
con.setAutoCommit(true);
}
}
public void setDelegates(List<ItemWriter<? super T>> delegates) {
super.setDelegates(delegates);
this.delegates = delegates;
}
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
这篇关于Spring Batch CompositeItemWriter 事务回滚问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!