重复的Spring Batch作业实例 [英] Duplicate Spring Batch Job Instance

查看:493
本文介绍了重复的Spring Batch作业实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小型的Spring Batch应用程序示例,该应用程序在初次启动时可以正常工作,但是每当我关闭该应用程序时&重新启动jar,我总是会收到此错误:

I have a small sample Spring Batch application that when started for the first time will work fine but whenever I shut the application down & restart the jar I always get this error:

Caused by: org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; Duplicate entry '1' for key 1; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 1

我不确定作业增量器设置是否错误.但是就像我说的,我可以启动它然后使用Web服务URL /jobLauncher.html任意次调用批处理.只有在我关闭应用程序&重新启动它,我得到这个错误.它想为作业执行表使用ID 1,但以前的运行中已经有ID 1.

I'm not sure if I have the job incrementer setup wrong. But like I said I can start it up & then use the web service url, /jobLauncher.html, to invoke the batch process any number of times just fine. It's only after I shutdown the application & restart it that I get this error. It wants to use id 1 for the job execution table but id 1 is already there from the previous runs.

主班

@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, new String[]{ "date=" + System.currentTimeMillis() });
    }
}

Web服务类

@Controller
public class JobLauncherController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/jobLauncher.html")
    @ResponseBody
    public String handle() throws Exception{
        jobLauncher.run(job, new JobParametersBuilder().addString("date", System.currentTimeMillis() + "").toJobParameters());
        return "Started the batch...";
    }
}

Spring Batch类

Spring Batch class

@Configuration
@EnableBatchProcessing
public class SampleBatchApplication {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    protected Tasklet tasklet() {
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution,
                                        ChunkContext context) {
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Job job() throws Exception {
        return this.jobs.get("job")
                   .incrementer(new RunIdIncrementer())
                   .flow(this.step1())
                   .end()
                   .build();
    }

    @Bean
    protected Step step1() throws Exception {
        return this.steps.get("step1").tasklet(this.tasklet()).build();
    }

    @Bean
    public DataSource dataSource() {

        BasicDataSource ds = new BasicDataSource();

        try {
            ds.setDriverClassName("com.mysql.jdbc.Driver");
            ds.setUsername("test");
            ds.setPassword("test");
            ds.setUrl("jdbc:mysql://127.0.0.1:3306/spring-batch");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ds;
    }
}

推荐答案

发现了问题.在Spring Boot中使用@EnableAutoConfiguration批注时,它将调用org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration类,该类将从'schema-mysql.sql'文件初始化数据库.

Found the issue. When using the @EnableAutoConfiguration annotation from Spring Boot it will invoke the org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration class which will initialize the database from the 'schema-mysql.sql' file.

Inside the schema-mysql.sql file is some code to reset the sequence id's for the batch meta tables which is why I was getting a duplicate key error:

INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
INSERT INTO BATCH_JOB_SEQ values(0);

解决方法是分别构建Spring Batch表&然后将@EnableAutoConfiguration批注更改为:

The fix was to build the Spring Batch tables separately & then change the @EnableAutoConfiguration annotation to:

@EnableAutoConfiguration(exclude={BatchAutoConfiguration.class})

以便应用程序启动时不会尝试初始化Spring Batch表.

so that when the application starts up it will not try to initialize the Spring Batch tables.

要为其他组件排除或自定义Spring Boot的自动配置,您可以在此处找到一些文档:

To exclude or customize Spring Boot's auto-configuration for other components you can find some docs here: http://projects.spring.io/spring-boot/docs/spring-boot-autoconfigure/README.html

BatchAutoConfiguration代码: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration .java

The BatchAutoConfiguration code: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java

这篇关于重复的Spring Batch作业实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆