Search code examples
javaspringspring-bootspring-batchbatch-processing

scheduling more than one batch job in spring boot application


My spring boot batch application has a scheduler which schedules my batch job written in FirstBatchConfiguration class to run every hour.

I have another batch job which I have configured in SecondBatchConfiguration class in the same application which i will be scheduling to run once in a week, but I am not able to figure out how to schedule it in the same JobScheduler so that both jobs should run at their own scheduled times.

If someone could help me to achieve this.

My current scheduler is:

@Component
public class JobScheduler {

    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private FirstBatchConfiguration firstBatchConfiguration;

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void runJob() {

        Map<String, JobParameter> confMap = new HashMap<>();
        confMap.put("time", new JobParameter(System.currentTimeMillis()));
        JobParameters jobParameters = new JobParameters(confMap);
        final Logger logger = LoggerFactory.getLogger("applicationlogger");

        try {

            jobLauncher.run(firstBatchConfiguration.firstJob(), jobParameters);

        } catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
                | JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {

            logger.error(e.getMessage());
        }
    }

}

Solution

  • If the program have to run a second schedule then add a new method with Schedule annotation for example @Scheduled(cron = "5 8 * * 6 ?"). If you need to use the SecondBatchConfiguration class then just Autowired it.

    1. Step1 (autowired your configuration) @Autowired your SecondBatchConfiguration

    Example:

    @Autowired
    private SecondBatchConfiguration secondBatchConfiguration;
    
    1. Create a new method and schedule it with @Scheduled annotation, and in the method body launch the second job.

    Example:

    @Scheduled(cron = "5 8 * * 6 ?")
    public void runSecondJob() { ... }
    

    You can have multiple schedules as many as you need, and every one with its own schedule.

    @Scheduled(cron = "5 8 * * 6 ?")
    public void runSecondJob() { .... }
    
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void runJob() { .... }
    

    EDIT: Asynchronous Job Execution

    Async job excecution is a very powerful feature of spring batch, there is a good documentation and examples about it.

    Please see the following instructions in order to activate async job exception:

    Step 1: Add Job Configuration (this alternative is using In-Memory JobRepository). To read more about repository types go to Spring Documentation

    Create a ResourcelessTransactionManager Bean

       @Bean
        public ResourcelessTransactionManager transactionManager() {
            return new ResourcelessTransactionManager();
        }
    

    Create MapJobRepositoryFactory Bean

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
            ResourcelessTransactionManager txManager) throws Exception {
        MapJobRepositoryFactoryBean factory = new
                MapJobRepositoryFactoryBean(txManager);
        factory.afterPropertiesSet();
        return factory;
    }
    

    Create JobRepository Bean

    @Bean
    public JobRepository jobRepository(
            MapJobRepositoryFactoryBean factory) throws Exception {
        return factory.getObject();
    }
    

    Create a ThreadPoolExecutor (ThreadPoolExecutor is responsible for Async execution, there are more types of executors and you can read more about them in Spring Documentation)

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setQueueCapacity(30);
        return taskExecutor;
    }
    

    Create a JobLauncher bean

       @Bean
        public JobLauncher jobLauncher(ThreadPoolTaskExecutor taskExecutor, JobRepository jobRepository){
            SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
            jobLauncher.setTaskExecutor(taskExecutor);
            jobLauncher.setJobRepository(jobRepository);
            return jobLauncher;
        }
    

    Step 2: Enable Async Job Execution

    Go to you Spring Boot Application Class and the following Annotations

    @EnableBatchProcessing
    @EnableAsync
    @EnableScheduling
    @SpringBootApplication
    public class MyBatchApp {