gpt4 book ai didi

spring-batch - ItemWriter异常时如何防止回滚?

转载 作者:行者123 更新时间:2023-12-05 05:09:06 28 4
gpt4 key购买 nike

我们的编写器旨在将记录写入关系数据库。如果任何记录发生异常,Spring Batch 将对 block 中的每条记录执行回滚和重试写入操作。这会导致发生 SQL Duplicate Key 异常,因为 block 中先前处理的记录已成功写入数据库。

我们尝试使用 noRetry() 和 noRollback(),明确指定不应触发重试或回滚的异常列表。

根据 Spring Batch 在线文档,noRollback() 可用于在 ItemWriter 发生错误时防止回滚:https://docs.spring.io/spring-batch/4.1.x/reference/html/step.html#controllingRollback

但是,这与源代码中的 java 文档相矛盾,后者指出 FaultTolerantStepBuilder.noRollback() 在写入期间被忽略: https://docs.spring.io/spring-batch/4.1.x/api/index.html?org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.html

这是我们的工作定义示例:

    @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;
}
};
}

我们预期的行为是写入中发生的异常不会触发重试或回滚。这将防止重复调用数据库,因此不会导致 SQL 重复键异常。

最佳答案

不是解决方案,但至少解释了为什么框架的行为不像您预期​​的那样,我在 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); }

关于spring-batch - ItemWriter异常时如何防止回滚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57793522/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com