Spring Batch注释分区器问题

时间:2015-05-14 09:19:40

标签: spring spring-batch

我正在尝试使用基于注释的方法创建一个Spring批处理应用程序,该方法将由quartz scheduler触发,但会遇到以下问题。

  1. 当触发作业时,每个分区按顺序执行而不是并行执行,即如果我有10个分区而不是所有10个分区被一起触发/处理,则逐个处理。

  2. 当多个作业实例(根据我的要求需要)被触发时,它没有正确同步,即当第二个实例启动时,它使用第一个实例数据,第一个实例将停止处理但将处于活动状态

  3. 以下是我的配置/类文件。

    BatchConfiguration.java -

    @Configuration
    @EnableBatchProcessing
    public class BatchConfiguration
    {
    @Autowired
    private JobBuilderFactory jobBuilders;
    
    @Autowired
    private StepBuilderFactory stepBuilders;
    
    @Bean
    @StepScope
    public JdbcCursorItemReader reader(@Value("#{stepExecutionContext[someParam]}") String someParam) {
        JdbcCursorItemReader jdbcCursorItemReader = new JdbcCursorItemReader();
        jdbcCursorItemReader.setDataSource(getDataSource());
        jdbcCursorItemReader.setSql("myQuery");
        jdbcCursorItemReader.setRowMapper(new NotifRowMapper());
        return jdbcCursorItemReader;}
    
    @Bean
    @StepScope
    public MyProcessor processor() {
        return new MyProcessor();}
    
    @Bean
    public MyPartitioner partitioner() {
        MyPartitioner partitioner = new MyPartitioner();
        partitioner.setDataSource(getDataSource());
        partitioner.setSql("MyPartitionerQuery");
        return partitioner;}
    
    @Bean
    @StepScope
    public JdbcBatchItemWriter writer(DataSource dataSource) {
        JdbcBatchItemWriter writer = new JdbcBatchItemWriter();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
        writer.setSql("MyWriterQuery");
        writer.setDataSource(dataSource);
        return writer;}
    
    @Bean
    public Job springBatch() {
        return jobBuilders.get("springBatch").start(masterStep()).build();}
    
    @Bean
    public Step masterStep() {
        return stepBuilders.get("masterStep")
        .partitioner(slave(reader(null), writer(getDataSource()),processor()))
        .partitioner("slave", partitioner())
        .taskExecutor(taskExecutor()).build();}
    
    @Bean
    public Step slave(JdbcCursorItemReader reader,JdbcBatchItemWriter writer, MyProcessor processor) {
        return stepBuilders.get("slave")
        .chunk(100).reader(reader).processor(processor).writer(writer).build();}
    
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setMaxPoolSize(20);
        taskExecutor.afterPropertiesSet();
        return taskExecutor;}
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);}
    
    @Bean
    public DataSource getDataSource() {
        return dataSource;
    }
    
    @Bean
    public JobRepository getJobRepository() throws Exception {
        MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
        factory.setTransactionManager(new ResourcelessTransactionManager());
        factory.afterPropertiesSet();
        factory.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
        return (JobRepository) factory.getObject();
    }}
    

    QuartzJob.java(触发弹簧批处理作业) -

    public class QuartzJob implements org.quartz.Job
    {
    @Override
    public void execute(org.quartz.JobExecutionContext jobExecutionContext) throws org.quartz.JobExecutionException
    {
        AnnotationConfigApplicationContext context;
        try
        {
            context = new AnnotationConfigApplicationContext(BatchConfiguration.class);
            JobLauncher jobLauncher = context.getBean(JobLauncher.class);
            org.springframework.batch.core.Job newJob = context.getBean("springBatch", org.springframework.batch.core.Job.class);
            JobParameters param = new JobParametersBuilder().addLong("time",System.currentTimeMillis()).toJobParameters();
            jobLauncher.run(newJob, param);
    
        } catch (Exception e){}}}
    

    MyQuartzListener.java(类在服务器启动期间触发quartz作业) -

    public class MyQuartzListener implements ServletContextListener
    {
    private Scheduler scheduler;
    
    @Override
    public void contextDestroyed(ServletContextEvent arg0){ }
    
    @Override
    public void contextInitialized(ServletContextEvent ctx)
    {
        JobDetail job = JobBuilder.newJob(QuartzJob.class).withIdentity("SPRINGBATCH", "SPRINGBATCH").build();
    
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("SPRINGBATCH", "SPRINGBATCH").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(60).repeatForever()).build();
    
        try
        {
            scheduler = ((StdSchedulerFactory) ctx.getServletContext().getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY)).getScheduler();
            job.getJobDataMap().put("quartztime", System.currentTimeMillis());
            scheduler.scheduleJob(job, trigger);
        } catch (SchedulerException e) {} }
    

    }

    MyPartitioner .java

    public class MyPartitioner implements Partitioner
    {
    @Override
    public Map<String, ExecutionContext> partition(int gridSize)
    {
        Map<String, ExecutionContext> partitionMap = new HashMap<String, ExecutionContext>();
        List<String> partitionCodes = getPartitionCodes(sql);
        int count = 1;
    
        for (String partitionCode : partitionCodes)
        {
            ExecutionContext context = new ExecutionContext();
            context.put("partitionCode", partitionCode);
            context.put("name", "Thread" + count);
            partitionMap.put(partitionCode, context);
            count++;
        }
        return partitionMap;}}
    

    此配置有问题吗?我将当前时间传递给每个工作实例以单独识别每个实例,但仍然无法正常工作。

0 个答案:

没有答案