Spring batch 当ItemWriter中发生异常时,如何防止回滚?
我们的编写器设计用于将记录写入关系数据库。 如果任何记录发生异常,Spring Batch将对区块中的每条记录执行回滚并重试写入操作。这导致发生SQL重复密钥异常,因为区块中先前处理的记录已成功写入数据库 我们已经尝试使用noRetry()和noRollback(),显式地指定了不应触发重试或回滚的异常列表 根据Spring Batch在线文档,当ItemWriter发生错误时,可以使用noRollback()来防止回滚: 但是,这与源代码中的java文档相矛盾,源代码中说在写入过程中忽略FaultTolerantStepBuilder.noRollback() 以下是我们的工作定义示例:Spring batch 当ItemWriter中发生异常时,如何防止回滚?,spring-batch,Spring Batch,我们的编写器设计用于将记录写入关系数据库。 如果任何记录发生异常,Spring Batch将对区块中的每条记录执行回滚并重试写入操作。这导致发生SQL重复密钥异常,因为区块中先前处理的记录已成功写入数据库 我们已经尝试使用noRetry()和noRollback(),显式地指定了不应触发重试或回滚的异常列表 根据Spring Batch在线文档,当ItemWriter发生错误时,可以使用noRollback()来防止回滚: 但是,这与源代码中的java文档相矛盾,源代码中说在写入过程中忽略Fau
@Bean("my-job")
public Job job(Step step) {
return jobBuilderFactory.get("my-job")
.start(step)
.build();
}
@Bean
public Step step() {
return stepBuilderFactory.get("skip-step")
.<String, String>chunk(3)
.reader(reader())
.processor(myprocessor())
.writer(this::write)
.faultTolerant()
.skipLimit(1)
.skip(JobSkippableException.class)
.noRollback(JobSkippableException.class)
.noRetry(JobSkippableException.class)
.processorNonTransactional()
.build();
}
public ItemReader<String> reader() {
return new ItemReader<String> () {
@Override
public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
String s = randomUUID().toString();
logger.debug("READ STRING {}", s);
return s;
}
};
}
public void write(List<? extends String> items) {
for(String s : items) {
logger.debug("WRITE STRING {}", s);
throw new JobSkippableException("My skippable exception");
}
}
public ItemProcessor <String, String> myprocessor() {
return new ItemProcessor<String, String>() {
@Override
public String process(String item) throws Exception {
logger.debug("PROCESS STRING {}", item);
return item;
}
};
}
@Bean(“我的工作”)
公共职务职务(步骤){
return jobBuilderFactory.get(“我的工作”)
.开始(步骤)
.build();
}
@豆子
公共步骤(){
返回stepBuilderFactory.get(“跳过步骤”)
.chunk(3)
.reader(reader())
.processor(myprocessor())
.writer(this::write)
.容错()
.skipLimit(1)
.skip(JobSkipableException.class)
.noRollback(JobSkippableException.class)
.noRetry(JobSkipableException.class)
.processorNonTransactional()
.build();
}
公共项目阅读器(){
返回新的ItemReader(){
@凌驾
public String read()引发异常、UnexpectedInputException、ParseException、NonTransientResourceException{
字符串s=randomUUID().toString();
debug(“读取字符串{}”,s);
返回s;
}
};
}
public void write(List不是一个解决方案,但至少是一个解释,解释了为什么框架的行为不像我在FaultTolerantChunkProcessor
的第335-350行中看到的那样:
try {
doWrite(outputs.getItems());
}
catch (Exception e) {
if (rollbackClassifier.classify(e)) {
throw e;
}
/*
* If the exception is marked as no-rollback, we need to
* override that, otherwise there's no way to write the
* rest of the chunk or to honour the skip listener
* contract.
*/
throw new ForceRollbackForWriteSkipException(
"Force rollback on skippable exception so that skipped item can be located.", e); }
可能的重复可能的重复