Spring Batch In-memory (MapJobRepositoryFactoryBean) очищает старые задания, а не запущенное задание - PullRequest
1 голос
/ 14 марта 2020

Я использую Spring-Batch, чтобы запланировать пакетное задание. ie В оперативной памяти как требование проекта c (ie не в производственной среде, предназначенной только для среды тестирования), ниже приведены мои классы конфигурации, которые выглядят как

// Batch Scheulder class
    package org.learning.scheduler
    import org.springframework.batch.core.explore.JobExplorer;
    import org.springframework.batch.core.explore.support.SimpleJobExplorer;
    import org.springframework.batch.core.launch.support.SimpleJobLauncher;
    import org.springframework.batch.core.repository.JobRepository;
    import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
    import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.task.SimpleAsyncTaskExecutor;
    import org.springframework.scheduling.annotation.EnableScheduling;

    /**
     * Job Inmemory Config
     * 
     */
    @EnableScheduling
    @Configuration
    public class InmemoryJobConfig  {


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

        @Bean
        public MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean(ResourcelessTransactionManager resourcelessTransactionManager) throws Exception {
            MapJobRepositoryFactoryBean factoryBean = new MapJobRepositoryFactoryBean(resourcelessTransactionManager);
            factoryBean.afterPropertiesSet();
            return factoryBean;
        }

        @Bean
        public JobRepository jobRepository(MapJobRepositoryFactoryBean factoryBean) throws Exception{
            return (JobRepository) factoryBean.getObject();
        }
        @Bean
        public JobExplorer jobExplorer(MapJobRepositoryFactoryBean repositoryFactory) {
            return new SimpleJobExplorer(repositoryFactory.getJobInstanceDao(), repositoryFactory.getJobExecutionDao(),
                    repositoryFactory.getStepExecutionDao(), repositoryFactory.getExecutionContextDao());
        }

        @Bean
        public SimpleJobLauncher jobLauncher(JobRepository jobRepository) throws Exception {
            SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
            simpleJobLauncher.setJobRepository(jobRepository);
            simpleJobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());

            return simpleJobLauncher;
        }
    }

//Job ConfiguratinClass

/**
 * Batch Entry Point for Scheduler for all Jobs
 *
 * 
 */
@Import({InmemoryJobConfig.class})
@EnableBatchProcessing
@Configuration
@Slf4j
public class BatchScheduler {


    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    private SimpleJobLauncher jobLauncher;


    @Autowired
    private JobExplorer jobExplorer;

    @Autowired
    private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;


    @Bean
    public ItemReader<UserDTO> userReader() {
        return new UserReader();

    }

    @Bean
    public ItemWriter<User> userWriter() {
        return new UserWriter();

    }

    @Bean
    public ItemReader<OrderDTO> orderReader() {
        return new OrderReader();
    }

    @Bean
    public ItemWriter<Order> orderWriter() {
        return new OrderWriter();
    }

    @Bean
    public Step userStep(ItemReader<UserDTO> reader, ItemWriter<User> writer) {
        return steps.get("userStep")
                .<UserDTO, User>chunk(20)
                .reader(userReader())
                .processor(new UserProcessor())
                .writer(userWriter())
                .build();
    }

    @Bean
    public Step orderStep(ItemReader<OrderDTO> reader, ItemWriter<Order> writer) {
        return steps.get("orderStep")
                .<OrderDTO, Order>chunk(20)
                .reader(orderReader())
                .processor(new OrderProcessor())
                .writer(orderWriter())
                .build();
    }


    @Bean
    public Job userJob() {
        return jobs.get("userJob").incrementer(new RunIdIncrementer()).start(userStep(userReader(), userWriter())).build();
    }

    @Bean
    public Job orderJob() {
        return jobs.get("orderJob").incrementer(new RunIdIncrementer()).start(orderStep(orderReader(), orderWriter())).build();
    }


    @Scheduled(cron = "0 0/15 * * *  ?")
    public void scheduleUserJob() throws JobExecutionException {
        Set<JobExecution> runningJob = jobExplorer.findRunningJobExecutions("userJob");

        if (!runningJob.isEmpty()) {
            throw new JobExecutionException(" User Job  is already in Start State  ");
        }

        JobParameters userParam =
                new JobParametersBuilder().addLong("date", System.currentTimeMillis())
                        .toJobParameters();
        jobLauncher.run(userJob(), userParam);

    }

    @Scheduled(cron = "0 0/15 * * *  ?")
    public void scheduleOrderJob() throws JobExecutionException {
        Set<JobExecution> runningJob = jobExplorer.findRunningJobExecutions("orderJob");

        if (!runningJob.isEmpty()) {
            throw new JobExecutionException(" Order Job  is already in Start State  ");
        }

        JobParameters orderParam =
                new JobParametersBuilder().addLong("date", System.currentTimeMillis())
                        .toJobParameters();
        jobLauncher.run(orderJob(), orderParam);

    }

    @Scheduled(cron = "0 0/30 * * *  ?")
    public void scheduleCleanupMemoryJob() throws BatchException {
        Set<JobExecution> orderRunningJob = jobExplorer.findRunningJobExecutions("orderJob");
        Set<JobExecution> userRunningJob = jobExplorer.findRunningJobExecutions("userJob");
        if (!orderRunningJob.isEmpty() || !userRunningJob.isEmpty()) {
            throw new BatchException(" Order/user Job  is running state , cleanup job is aborted  ");
        }

        mapJobRepositoryFactoryBean.clear();

    }
}

У меня запланировано два задания на каждые 0/15 минут, которые будут выполнять некоторые бизнес-логи c, и у меня запланировано задание очистки в памяти для очистки данных задания в памяти из "mapJobRepositoryFactoryBean" bean-компонент, только если какое-либо из этих двух заданий не запущено.

Я хочу предложить наилучший подход к удалению уже выполненных старых заданий. Приведенный выше подход не удалит старые сведения о задании, если его любое из заданий находится в рабочем состоянии.

Или есть какие-либо API-интерфейсы из Spring-Batch для очистки указанных подробностей задания c из оперативной памяти после выполнения задания.? ie очистка в памяти по JobId

Примечание : я хочу go с MapJobRepositoryFactoryBean только не постоянная база данных или любая встроенная база данных (H2)

1 Ответ

1 голос
/ 17 марта 2020

MapJobRepository предоставляет метод clear(), который очищает все данные в хранилище заданий на основе карты, но я не вижу очевидного способа удалить метаданные указанного c job.

Я хочу go с MapJobRepositoryFactoryBean только непостоянная база данных или любая встроенная база данных (H2)

Я действительно рекомендую использовать работу на основе JDB C хранилище с БД в памяти вместо. Этот подход лучше, потому что он позволяет вам выполнять запросы к вашей базе данных в памяти и удалять данные для определенного задания c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...