1

我在生产中有一个 Spring Batch 部署,它最初是使用 H2 数据源作为作业存储库开发的。最初的努力一切都很好,但是随着我们对 Spring Batch 的使用扩展,我们希望用更传统的数据库替换 H2。无论好坏(这不完全是我的决定),我将改用 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'

我查看了schema-*.sqlSpring Batch 用于创建其作业存储库表的“”脚本。其他数据库类型(例如 H2、Oracle、Postgres 等)创建三个序列... BATCH_STEP_EXECUTION_SEQ、、BATCH_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 的步骤?提前致谢!

4

1 回答 1

1

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

使用 H2,这很好……只要jdbc:initialize-database元素包含该ignore-failures="ALL"属性,您就不会真正注意到问题。

但是,MySQL 特定的序列解决方法不是您可以重复执行而不会弄乱 Spring Batch 的东西。

jdbc:initialize-database从我的 Spring Batch 配置中删除了该元素,在一个空数据库中手动执行了classpath:/org/springframework/batch/core/schema-mysql.sql一次该设置脚本,并且我的工作可以很好地运行多个调用。

于 2013-01-15T21:50:19.173 回答