我有一个spring批处理应用程序(spring boot 2.3.5版),它在spring批处理时使用一个JpaRepository将一些自定义日志消息插入数据库。这与开箱即用的spring批处理表是分开的。似乎当我从ItemProcessorAdapter抛出异常时,它会被ItemProcessListener onProcessError()方法捕获。在这个方法中,我执行一个JpaRepository save()和flush()。不会记录任何错误,但是一旦我离开这个方法,JpaRepository就会回滚。
下面是示例代码段。
java prettyprint-override">
@Configuration
public class BatchJobConfiguration {
//Omitted for clarity....
@Bean
@StepScope
public CompositeItemProcessor<Decision,Decision> itemProcessor() {
CompositeItemProcessor<Decision,Decision> itemProcessor = new CompositeItemProcessor<>();
itemProcessor.setDelegates(Arrays.asList(
decisionValidatingItemProcessor(),
myItemProcessor(null)
));
return itemProcessor;
} // end itemProcessor()
@Bean
public BeanValidatingItemProcessor<Decision> decisionValidatingItemProcessor() {
BeanValidatingItemProcessor<Decision> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
beanValidatingItemProcessor.setFilter(true);
return beanValidatingItemProcessor;
} // end decisionValidatingItemProcessor()
@Bean
public ItemProcessorAdapter<Decision,Decision> myItemProcessor(DecisionProcessingService service) {
ItemProcessorAdapter<Decision,Decision> adapter = new ItemProcessorAdapter<>();
adapter.setTargetObject(service);
adapter.setTargetMethod("processDecision");
return adapter;
}
@Bean
@StepScope
public DecisionItemProcessListener decisionItemProcessListener() {
return new DecisionItemProcessListener(mpJpaRepository);
}
}
@Service
public class DecisionProcessingService {
public Decision processDecision(Decision decision) throws BatchException {
....
throw new BatchException("An error occurred");
}
}
public class DecisionItemProcessListener implements ItemProcessListener<Decision,Decision> {
private MyJpaRepository mpJpaRepository;
public DecisionItemProcessListener(MyJpaRepository mpJpaRepository) {
this.mpJpaRepository = mpJpaRepository;
}
....
@Override
public void onProcessError(Decision decision, Exception e) {
MyEntityObject obj = MyEntityObject.builder()
.msg(e.getMessage())
.build();
mpJpaRepository.save(obj);
mpJpaRepository.flush();
// after this, the insert above is rolled back.
} // end onProcessError()
}
您在这里使用的回调ItemProcessListener#OnProcessError
是在一个事务(由spring批处理驱动)中调用的,该事务将由于项处理器引发的异常而回滚。
如果要在该方法中保存数据,则需要使用新事务(使用requires_new
传播)。
编辑:我在这里分享了一个最小的完整示例:https://github.com/benas/spring-batch-lab/tree/master/issues/so64913980。
问题内容: 我的问题与春季批次和交易有关。 假设我为我的步骤之一选择了 50 的 提交间隔 。 还要假设我总共有1000条记录,其中一条记录将导致itemWriter失败,从而导致整个块的回滚(在我的示例中为50条记录)。 确保作业完成(并忽略有问题的块)后将49个有效记录写入数据库的状态有哪些? 问题答案: 经过研究,我得出以下结论: 如果项目编写者未能提交一个块(此处为50个项目)从而导致回滚
在我的项目中配置了以下内容: 加载文件时,我有重复的记录,但因为我配置了在下,Spring batch不应回滚记录,但仍将回滚记录。如果我从列表中删除,那么它将抛出异常。我们正在使用Spring批处理版本: 不希望回滚记录,但会回滚记录。
我有一个compositeItemWriter,它有2个代理编写器:1。HeaderWriter将一些字段从我的对象写入头表2。DetailWriter将文件写入详细表。 context.xml:
我有一个Spring批处理作业,它通过SFTP从远程Linux服务器检索文件。远程服务器上的目录是一个包含七天文件(约400个文件)的存档。文件的大小相对较小。 Spring批处理知道哪些文件已经被处理。 当我启动应用程序时。第一次,Spring Batch tasklet检索文件时,Spring Batch会为它已经处理的每个文件生成一个异常: > 在Transformer类中,是否应该检查文件
我有以下工作要处理在一定的时间间隔或特别的基础上。 作业中的步骤如下: 我也想要用户界面,在那里我可以触发一个特别的基础上的工作,而且我应该能够提供参数从用户界面。 我想用Spring batch来完成这个任务,但它更多的是用于读->处理->写之类的工作。这里,在第一步中,我正在生成由第二步读取的数据。我不确定我是否还可以使用Spring batch来实现这个,或者有更好的方法来实现这个。