SoFunction
Updated on 2025-04-13

Cause analysis and solution for Spring timed tasks to be executed only once

1. Problem background

During the development process, we often need to perform timing tasks, such as timed refreshing caches, cleaning temporary data, etc. Spring provides@ScheduledAnnotation, it can easily implement timing tasks. However, sometimes we find that the task is executed only once and will not be triggered later. For example:

@Component
@Slf4j
public class MediaAdIdCache {
    @Scheduled(fixedRate = 60 * 1000) // Expected to be executed once per minute    public void refreshCache() {
        ("Refresh the cache...");
    }
}

ifrefreshCache()It was only executed once, and we need to troubleshoot the cause and fix it.

2. Basic usage of Spring timed tasks

Spring's@ScheduledAnnotation supports three ways:

  • fixedRate: Fixed frequency execution (fixed time interval after the last task started)
  • fixedDelay: Fixed delayed execution (fixed time interval after the last task ends)
  • cron: Cron expression controls execution time

Example:

@Scheduled(fixedRate = 5000) // Execute every 5 secondspublic void task1() {
    ("Fixed Rate Task");
}

@Scheduled(fixedDelay = 3000) // Execute again 3 seconds after the last task is overpublic void task2() {
    ("Fixed Delay Task");
}

@Scheduled(cron = "0 * * * * ?") // Execute once per minutepublic void task3() {
    ("Cron Task");
}

3. Why are timed tasks only executed once?

3.1 Scheduling support is not enabled (@EnableScheduling)

Cause of the problem:

  • Spring Boot will not automatically scan by default@ScheduledAnnotation, scheduling support must be enabled explicitly.

Solution:

  • Add on main class or configuration class@EnableScheduling
@SpringBootApplication
@EnableScheduling // Key notespublic class MyApp {
    public static void main(String[] args) {
        (, args);
    }
}

3.2 The task throws an uncaught exception

Cause of the problem:

  • If the timing task throws an uncaught exception, Spring may terminate subsequent scheduling.

Example:

@Scheduled(fixedRate = 5000)
public void errorTask() {
    throw new RuntimeException("Simulate exception");
}

Solution:

  • usetry-catchCatch exception:
@Scheduled(fixedRate = 5000)
public void safeTask() {
    try {
        // Business logic    } catch (Exception e) {
        ("Task execution failed", e);
    }
}

3.3 Thread pool problem causes task blockage

Cause of the problem:

  • Spring uses a single thread to execute timing tasks by default. If a task takes too long, other tasks will be blocked.

Solution:

  • Custom thread pool:
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ((5));
    }
}

3.4 Redis connection failure causes task interruption

Cause of the problem:

  • If the timing task depends on external services (such as Redis, database), connection failure may cause the task to be interrupted.

Solution:

  • Ensure external services are available and add retry mechanisms:
@Scheduled(fixedRate = 60 * 1000)
public void refreshCache() {
    try {
        Set<String> ids = ().members("key");
        // Business logic    } catch (Exception e) {
        ("Redis operation failed", e);
    }
}

4. Solution summary

question Solution
Not enabled@EnableScheduling Add in main class@EnableScheduling
The task throws an exception usetry-catchCatch exceptions
Single thread blocking Configure multi-threaded pools
External dependency failure Check connections and add error handling

5. Complete code example

5.1 Main startup class (enable scheduling)

@SpringBootApplication
@EnableScheduling
public class MyApp {
    public static void main(String[] args) {
        (, args);
    }
}

5.2 Timed task class (with exception handling)

@Component
@Slf4j
public class MediaAdIdCache {
    private final RedisTemplate<String, String> redisTemplate;

    public MediaAdIdCache(RedisTemplate<String, String> redisTemplate) {
         = redisTemplate;
    }

    @Scheduled(fixedRate = 60 * 1000) // Execute once per minute    public void refreshCache() {
        try {
            Set<String> ids = ().members("flowfilter:mediaAdId");
            ("Cache refresh successfully,quantity: {}", ());
        } catch (Exception e) {
            ("Failed to refresh the cache", e);
        }
    }
}

5.3 Custom thread pool (prevent blocking)

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ((5));
    }
}

6. Summary

Spring's@ScheduledThe timing tasks are only executed once, usually because:

  1. Scheduling not enabled (@EnableSchedulingMissing)
  2. Task throws exception (not handled correctly)
  3. Thread pool problem (single thread blocking)
  4. External dependency failure (such as Redis connection problem)

Through this article's analysis and solutions, you can effectively avoid the problem of timed task interruption and ensure that the task is executed as expected. If there are still problems, it is recommended to combine logging and debugging to further troubleshoot.

The above is the detailed content of the reason analysis and solution for Spring timed tasks only executed once. For more information about Spring timed tasks only executed once, please pay attention to my other related articles!