RetryTemplate 질문 드립니다.
618
작성한 질문수 3
안녕하세요 이번 강의에서 RetryItemProcessor2 클래스에서
new DefaultRetryState(item, rollbackClassifier)를 추가하게 되면서 retry가 1번만 발생하게 되더라고요.
Configuration에서 RetryPolicy로 maxAttempts를 2로 줬는데 왜 1번만 retry를 하는걸까요?
제가 디버깅하면서 보니까 처음 재시도때는 RetryPolicy가 Configuration에서 정의한 RetryPolicy가 적용됐는데, 2번째 재시도 하려고 할때 RetryPolicy가 SimpleRetryPolicy가 maxAttempts가 0인상태로, configuration에서 정의한 RetryPolicy가 아니더라고요.
왜 이렇게 된건지 알고싶습니다.
답변 3
1
네
위 소스를 보시면 maxAttempts를 2 를 설정한 것은 우리가 직접 RetryTemplate 빈을 생성할 때 정의한 값입니다.
즉 faultTolerant() 설정에서 별도의 설정을 하지 않는다면 스프링 배치가 초기화 되면서 생성되는 RetryTemplate retryLimit 의 기본 maxAttempts 값은 0 입니다.
순서로 보면 예외가 발생할 경우 스프링 배치의 RetryTemplate 이 먼저 실행되고 그 다음 RetryItemProcess2 에 선언된 RetryTemplate 가 실행됩니다.
@Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1")
.<String, Customer>chunk(5)
.reader(reader())
.processor(processor())
.writer(writer())
.faultTolerant()
// .retry(RetryableException.class)
// .retryLimit(2)
// .skip(RetryableException.class)
// .skipLimit(2)
.build();
}
그런데 위 소스에서 retryLimit 은 주석으로 되어 있기 때문에 maxAttempts 값은 0입니다.
만약 위 설정에서 maxAttempts 값을 2 로 주었다면 스프링 배치의 기본 RetryTemplate 도 두번의 재시도를 할 것이고 우리가 직접 생성한 RetryTemplate 도 두번의 재시도를 하게 됩니다.
결론적으로 각 RetryTemplate 에 설정한 maxAttempts 의 값에 따라 재시도가 결정되며 순서는 스프링 배치의 기본 RetryTemplate 가 먼저 실행되고 그 다음 직접 설정한 RetryTemplate 가 실행된다는 점을 기억하시면 될 것 같습니다.
0
여기 소스에서 new DefaultRetryState(item, rollbackClassifier)를 추가했을 경우 입니다.
Retry(3) 강의 27:40에서 실행 하셨을때의 경우 입니다.
public class RetryItemProcessor2 implements org.springframework.batch.item.ItemProcessor<String, Customer> {
@Autowired
private RetryTemplate retryTemplate;
private int cnt = 0;
@Override
public Customer process(String item) throws Exception {
System.out.println("ItemProcessor : " + item);
Classifier<Throwable, Boolean> rollbackClassifier = new BinaryExceptionClassifier(true);
Customer customer = retryTemplate.execute(
new RetryCallback<Customer, RuntimeException>() {
@Override
public Customer doWithRetry(RetryContext retryContext) throws RuntimeException {
System.out.println("item = " + item);
if (item.equals("1") || item.equals("2")) {
cnt++;
throw new RetryableException("Retry Exception!! cnt : " + cnt);
}
return new Customer(item);
}
},
new RecoveryCallback<Customer>() {
@Override
public Customer recover(RetryContext retryContext) throws Exception {
return new Customer(item);
}
},
new DefaultRetryState(item, rollbackClassifier)
);
return customer;
}
}
@Configuration
@RequiredArgsConstructor
public class RetryTemplateConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private int chunkSize = 5;
@Bean
public Job job() {
return jobBuilderFactory.get("batchjob")
.incrementer(new RunIdIncrementer())
.start(step1())
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<String, Customer>chunk(chunkSize)
.reader(new ItemReader<String>() {
int i = 0;
@Override
public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
i++;
System.out.println("ItemReader :" + i);
return i > 10 ? null : String.valueOf(i);
}
})
.processor(retryItemProcessor())
.writer(System.out::println)
.faultTolerant()
// .skip(RetryableException.class)
// .skipLimit(2)
// .retry(RetryableException.class)
// .retryLimit(2)
.build();
}
@Bean
public ItemProcessor<? super String, Customer> retryItemProcessor() {
return new RetryItemProcessor2();
}
@Bean
public RetryTemplate retryTemplate() {
Map<Class<? extends Throwable>, Boolean> exceptionClasses = new HashMap<>();
exceptionClasses.put(RetryableException.class, true);
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(2000);
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(2, exceptionClasses);
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(simpleRetryPolicy);
// retryTemplate.setBackOffPolicy(backOffPolicy);
return retryTemplate;
}
스프링 배치 버전 질문
0
139
1
소스코드가 어디에 있나요?
0
122
2
트랜잭션 예외
0
99
1
질문이 있습니다.
0
137
2
ChunkListener 에서 beforeChunk 의 실행 시점 관련 질문
0
143
2
여러 JOB 설정하는법
0
157
2
강의 자료 다른 방법 있을까요?
0
162
1
JobExecution과 JobExecutionContext와의 관계
0
197
2
특정 job만 실행
1
266
1
Batch 성능 질문
0
157
1
ItemReaderAdapter 종료
0
87
1
[ 강좌 Git 브랜치 문의 ] 섹션 9 > JdbcCursorItemReader, JpaCursorItemReader
0
187
2
Spring Batch 배포 질문
0
252
2
spring batch 버전
0
238
2
retry count 관련 질문
0
182
2
StepExecutionListener 의 afterStep 에서 return ExitStatus.FAILED 에 의한 동작에 의문이 갑니다.
0
341
2
jdbc, jpa 커서방식 조회 방식 차이 질문 (강사님께 답변 받고 싶습니다)
0
241
2
Multithread step과 AsyncItemProcessor
0
208
2
job 재실행
0
258
2
bean 생명주기 문제 도와주세요(@Scope("step"), @Autowired)
0
190
1
Multi-threaded-step과 Partitioning 차이 확인
0
183
2
jdbcCursorReader, jdbcPagingReader 질문
0
149
1
step muti-thread 질문
0
114
1
itemSteam open update close 질문
0
117
1





