Spring Batch:使用@Retryable和@EnableRetry注释重试tasklet

时间:2016-04-03 05:38:52

标签: spring spring-batch spring-retry

我有这个tasklet将文件上传到Amazon S3。现在,我想在每次抛出AmazonClientException时重试tasklet执行。我认为使用@Retryable注释将完成这项工作。

微进程:

@Component
@StepScope
@Retryable(value=AmazonClientException.class, stateful=true, backoff=@Backoff(2000))
public class S3UploadTasklet extends ArgsSupport implements Tasklet {

    @Autowired
    private S3Client s3Client;

    @Autowired
    private S3Properties s3Properties;

    private static final Logger LOGGER = LoggerFactory.getLogger(S3UploadTasklet.class);

    private static final String FILE_EXTENSION = ".gpg";

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        try {
            String localFilename = getTempOutputFilename() + FILE_EXTENSION;
            String s3Filename = s3Properties.getReportPath() + getS3OutputFilename() + FILE_EXTENSION;
            File f = new File(localFilename);
            if(f.exists()) {
                LOGGER.info("Uploading " + localFilename + " to s3...");
                s3Client.upload(localFilename, s3Filename, s3Properties.getBucketName());
                LOGGER.info("Uploading done!");
            } else {
                throw new RuntimeException("Encrypted file not found! Encryption process might have failed.");
            }
        } catch(AmazonClientException e) {
            LOGGER.error("Problems uploading to S3. " + e.getMessage(), e);
            throw e;
        } catch(RuntimeException e) {
            LOGGER.error("Runtime error occured. " + e.getMessage(), e);
            throw e;
        }

        return RepeatStatus.FINISHED;
    }
}

工作配置:

@Configuration
@EnableBatchProcessing
@EnableRetry
public class BatchConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private Step generateReport;

    @Autowired
    private Step encrypt;

    @Autowired
    private Step upload;

    @Autowired
    private Step cleanUp;

    @Bean
    @Transactional(value="appTransactionManager", isolation=Isolation.READ_COMMITTED)
    public Job generateReconJob() {
        return jobBuilderFactory.get("reconJob")
                .incrementer(new RunIdIncrementer())
                .start(generateReport)
                    .on("COMPLETED").to(encrypt)
                .from(generateReport)
                    .on("NOOP").end()
                .from(generateReport)
                    .on("FAILED").to(cleanUp)
                .from(encrypt)
                    .on("COMPLETED").to(upload)
                .from(encrypt)
                    .on("FAILED").to(cleanUp)
                .from(upload)
                    .on("*").to(cleanUp)
                .from(cleanUp)
                    .on("*").end()
                .end()
                .build();
    }
}

然而,它并没有做它应该做的事情。抛出异常时批处理作业仍然没有重试tasklet。

有什么想法吗?

这里的配置也是

@Configuration
public class ReportConfiguration {
   ...

   @Autowired
   private S3UploadTasklet s3UploadTasklet;

   ...

    @Bean
    public Step upload() {
        return stepBuilderFactory.get("upload")
                .tasklet(s3UploadTasklet)
                .build();
    }
}

1 个答案:

答案 0 :(得分:0)

@Retryable(value = AmazonClientException.class,stateful = true,backoff = @ Backoff(2000))注释应该在您要重试的方法上,而不是类。