You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@Scheduled与@Retryable联用重试机制未触发问题排查

Spring Boot中@Scheduled搭配@Retryable不生效的问题排查与解决

根因分析

  • 方法修饰符为protected导致AOP切面拦截失败
    @Retryable基于Spring AOP动态代理实现,默认JDK动态代理仅支持public方法拦截,即使用CGLIB代理,未显式配置的情况下也无法拦截protected方法,重试切面无法触发。
  • 未指定重试异常类型,默认不支持检查异常重试
    @Retryable默认仅对RuntimeException、Error类型的异常触发重试,你代码中声明抛出的JobExecutionAlreadyRunningException等均为检查型异常,默认不在重试触发范围内。
  • Spring Batch任务内部异常未透出到外层方法
    如果任务Step内部的异常被Spring Batch自带的容错机制(skip、内置重试等)捕获处理,没有透出到simpleJobLauncher.run()方法外层,runJob不会抛出异常,@Retryable无法感知到异常触发重试。

修复方案

  1. 将runJob方法的修饰符从protected改为public,符合Spring AOP的代理规则
  2. 在@Retryable注解中显式声明需要重试的异常类型,覆盖所有可能抛出的检查异常
  3. 确认Spring Batch任务的异常可以正常透出到runJob方法外层,没有被内部容错逻辑完全吞掉

修复后的代码示例:

@Component
public class JobRunnerStats {

    @Scheduled(cron = "0 0/2 * ? * *")
    @Retryable(
        maxAttempts = 10, 
        backoff = @Backoff(delay = 1000),
        include = {
            JobExecutionAlreadyRunningException.class,
            JobRestartException.class,
            JobInstanceAlreadyCompleteException.class,
            JobParametersInvalidException.class
        }
    )
    public JobExecution runJob() throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
        // 原有业务逻辑不变
        JobParameters jobParameters = null;
        if (this.jobParameters == null) {
            jobParameters = buildJobParameters(null);   
        } else {
            jobParameters = this.jobParameters;
            this.jobParameters = null;
        }
    
        return simpleJobLauncher.run(this.jobStats, jobParameters);
    }

}

内容的提问来源于stack exchange,提问作者Joe Taras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:39:01