将Spring Batch作业存储库数据库切换到MySQL时,序列不起作用

时间:2013-01-14 15:36:44

标签: spring spring-batch

我在生产中有一个Spring Batch部署,它最初是使用作业存储库的H2数据源开发的。这项初步工作一切正常,但我们希望用更传统的数据库替换H2,因为我们使用Spring Batch进行扩展。无论好坏(这不完全是我的决定),我转而使用MySQL。

我已将作业存储库的数据源从H2切换到MySQL,并将元素更改为使用“classpath:/org/springframework/batch/core/schema-mysql.sql”。当我第一次运行批处理作业时,Spring Batch会创建存储库表并毫无问题地运行我的作业。

然而,后续执行失败...即使我正在使用作业增量器,传递“-next”参数,并且看到它与H2一起工作正常。当我将日志记录设置为“调试”级别时,我看到后续执行时会出现以下异常:

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 'PRIMARY'; 
nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'

我查看了Spring Batch用于创建其作业存储库表的“schema-*.sql”脚本。其他数据库类型(例如H2,Oracle,Postgres等)创建三个序列...... BATCH_STEP_EXECUTION_SEQBATCH_JOB_EXECUTION_SEQBATCH_JOB_SEQ。我不是MySQL专家,但看起来MySQL缺乏对序列的支持......因为“schema-mysql.sql”包含这些行作为一个明显的解决方法:

CREATE TABLE BATCH_STEP_EXECUTION_SEQ (ID BIGINT NOT NULL) ENGINE=MYISAM;
INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (ID BIGINT NOT NULL) ENGINE=MYISAM;
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_SEQ (ID BIGINT NOT NULL) ENGINE=MYISAM;
INSERT INTO BATCH_JOB_SEQ values(0);

很明显,MySQL对序列和自动增量值的处理与其他数据库不同,因此假设Spring Batch必须做一些不同的事情来增加其作业存储库表中的ID。我需要采取其他一些特定于MySQL的步骤,我可能不知道吗?提前致谢!

1 个答案:

答案 0 :(得分:1)

问题是我在每个作业运行时都在执行classpath:/org/springframework/batch/core/schema-mysql.sql脚本。

使用H2,这很好......只要jdbc:initialize-database元素包含ignore-failures="ALL"属性,您就不会发现问题。

但是,对于序列的特定于MySQL的解决方法并不是可以在没有Spring Batch搞砸的情况下重复执行的。

我从Spring Batch配置中删除了jdbc:initialize-database元素,在空数据库中手动执行了classpath:/org/springframework/batch/core/schema-mysql.sql安装脚本一次,我的作业运行了多次调用就好了。