问题
I have Spring batch job with following config:
@Bean
public Job myJob(Step step1, Step step2, Step step3) {
return jobs.get("myJob").start(step1).next(step2).next(step3).build();
}
@Bean
public Step step1(ItemReader<String> myReader,
ItemProcessor<String, String> myProcessor,
ItemWriter<String> myWriter) {
return steps.get("step1").<String, String>chunk(1)
.reader(myReader)
.faultTolerant().retryLimit(3).retry(MyException.class)
.processor(myProcessor)
.writer(myWriter)
.build();
}
@Bean
@StepScope
public MyReader myReader() {
return new MyReader();
}
@Bean
public MyProcessor myProcessor() {
return new MyProcessor();
}
@Bean
public MyWriter myWriter() {
return new MyWriter();
}
When MyReader class throws MyException it is stopping the execution of the job without retrying with following stack trace:
2019-05-16 14:45:09.460 ERROR 22485 --- [ main] o.s.batch.core.step.AbstractStep : Encountered an error executing step step1 in job myJob
org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:116) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
回答1:
When MyReader class throws MyException it is stopping the execution of the job without retrying
The retry policy is not applied to the item reader. So even if you declare an exception as retryable and that exception is thrown from the reader, the retry policy is not invoked.
The retry policy is only applied to the processor and writer.
回答2:
Seems the retry functionality was pulled out of Spring Batch as of 2.2.0. It is now part of a new library, Spring Retry. https://docs-stage.spring.io/spring-batch/docs/current/reference/html/retry.html#retry
Steps to handle this with declarative retry:
Step 1:
Include @EnableRetry
in application
Spet 2: Add aop starter based on https://github.com/spring-projects/spring-retry#additional-dependencies
Gradle runtime('org.springframework.boot:spring-boot-starter-aop')
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>runtime</scope>
</dependency>
Spet 3:
Include @Retryable
in MyReader
@Override
@Retryable(include = { MyException.class }, maxAttempts = 5)
public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
Sample code is checked into github: https://github.com/atulkulkarni18/spring-batch-reader-retry
Sample output:
MyReader : 0
MyProcessor : 0
MyWriter : [0]
MyReader : 1
MyProcessor : 1
MyWriter : [1]
MyReader : 2
MyProcessor : 2
MyWriter : [2]
MyReader : 3
****
MyReader : 3
****
MyReader : 3
****
MyReader : 3
MyProcessor : 3
MyWriter : [3]
MyReader : 4
MyProcessor : 4
MyWriter : [4]
MyReader : 5
来源:https://stackoverflow.com/questions/56170179/retry-not-working-with-spring-batch-with-java-config