Spring Batch中StoredProcedureItemReader调用DB2存储过程失败排查
你遇到的核心问题其实分两部分:Spring Batch在启动时尝试访问作业元数据表但找不到,导致作业还没走到你自定义的StoredProcedureItemReader执行步骤就报错了,所以你的自定义查询根本没机会执行。
为什么会执行默认查询?
报错里的SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? order by JOB_INSTANCE_ID desc是Spring Batch的作业元数据查询,用来跟踪作业实例的运行状态。Spring Batch默认需要一套元数据表来管理作业的执行记录,如果你没有提前创建这些表,就会触发SQLCODE=-204的表不存在错误。
解决方案步骤
1. 初始化DB2的Spring Batch元数据表
Spring Batch针对不同数据库提供了现成的DDL脚本,DB2对应的脚本可以在spring-batch-core依赖的jar包中找到,路径是org/springframework/batch/core/schema-db2.sql。你需要在你的DB2数据库中执行这个脚本,创建BATCH_JOB_INSTANCE、BATCH_JOB_EXECUTION等一系列元数据表。
如果你用的是Spring Boot,可以通过配置自动初始化(仅推荐开发环境使用):
spring.batch.initialize-schema=always spring.batch.schema=classpath:org/springframework/batch/core/schema-db2.sql
2. 检查StoredProcedureItemReader的配置(作业正常启动后)
等元数据表创建完成后,作业就能走到读取步骤了,这时候再确认你的存储过程读取配置是否正确:
- 你设置了
setFunction(true),要确认DEVTEST.PP_GETALLPRINTREADY确实是DB2的函数而不是存储过程,如果是存储过程,需要把这个参数设为false。 - DB2的存储过程返回游标时,需要确保存储过程定义了输出游标参数,并且你的
RowMapper能正确映射游标返回的结果集。 - 你的
PreparedStatementSetter中注册了多个输出参数,但StoredProcedureItemReader主要用来读取存储过程返回的结果集(游标),如果你的存储过程是通过游标返回数据,不需要手动注册这些输出参数,只需要确保参数定义和存储过程匹配。
额外提示(测试场景专用)
如果你的场景不需要Spring Batch的元数据跟踪(不推荐生产环境这么做),可以通过配置让作业使用内存元数据存储,重启应用后作业记录会丢失:
@Bean public JobRepository jobRepository(PlatformTransactionManager transactionManager) throws Exception { MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); factory.setTransactionManager(transactionManager); return factory.getObject(); } @Bean public JobLauncher jobLauncher(JobRepository jobRepository) { SimpleJobLauncher launcher = new SimpleJobLauncher(); launcher.setJobRepository(jobRepository); return launcher; }
内容的提问来源于stack exchange,提问作者Abhilash Muthuraj

