【发布时间】:2016-08-30 06:07:44
【问题描述】:
我的问题与existing SO question 正好相反。
JdbcPagingItemReader 的行为似乎与该问题中描述的相反,即如果JdbcPagingItemReader 未找到任何记录,则作业被标记为FAILED。
日志表明作业被标记为FAILED,因为阅读器无法从病房的第1页获取页面,SELECT由于SQLCODE=-313而失败,即
-313 指定的主机变量数不等于参数标记数
因此,整个步骤被标记为失败,导致作业失败。
对于病房第1页的查询,排序键包含在SELECT中,如PAYMENT_ID > ?,我猜因为没有PAYMENT_IDs,所以找不到占位符的值所以错误。
在这种特殊情况下,如何忽略此错误并将作业标记为COMPLETE?
我尝试了 Trever Shick 在其他问题的回答中指定的解决方案并返回
if(stepExecution.getReadCount() == 0 ){
return ExitStatus.COMPLETED;
}
没有解决问题。
块大小和阅读器页面大小都等于 10 并且 THROTTLE_LIMIT=20。
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<RemittanceVO> syncReader, ItemWriter<RemittanceClaimVO> writer,
ItemProcessor<RemittanceVO, RemittanceClaimVO> processor) {
return stepBuilderFactory.get("step1")
.<RemittanceVO, RemittanceClaimVO> chunk(Constants.SPRING_BATCH_CHUNK_SIZE)
.reader(syncReader)
.listener(afterReadListener)
.processor(processor)
.writer(writer)
.taskExecutor(simpleAsyntaskExecutor)
.throttleLimit(Constants.THROTTLE_LIMIT)
.build();
}
不是完整的堆栈跟踪,而是来自日志的一行,
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT PAYMENT_ID,INSURED_LAST_NM,INSURED_FIRST_NM,LAST_NM,FIRST_NM,CONTRACT_NUM,CARRIER_CD,CARRIER_GROUP,CONTRACT_NUM,REL_AR_SEQ_NUM,FROM_DOS_DT,THRU_DOS_DT,BILL_AMT,RX_NUM_BP,CERT_NUM_LEFT_BP,MODIFIER,PROC_CD ,DEPOSIT_ID,PRNT_CONTRACT_NUM,REMIT_TYPE_CD AS RMT_TYPE FROM AR.PAYMENTS WHERE (CONTRACT_NUM IN (SELECT CONTRACT_NUM FROM AR.PAYMENTS WHERE RMTST_RF='M' AND DELETE_IND='N' GROUP BY CONTRACT_NUM ) AND DELETE_IND='N' AND RMTST_RF='M') AND ((PAYMENT_ID > ?)) ORDER BY PAYMENT_ID ASC FETCH FIRST 50 ROWS ONLY]; nested exception is com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-313, SQLSTATE=07004, SQLERRMC=null, DRIVER=4.11.77
PAYMENT_ID 列是我的排序键,AND ((PAYMENT_ID > ?)) 部分已由 Spring Batch 添加。
我的读者豆,
@Bean
public ItemReader<RemittanceVO> syncReader() {
SynchronizedItemStreamReader<RemittanceVO> syncReader = new SynchronizedItemStreamReader<RemittanceVO>();
syncReader.setDelegate(reader());
return syncReader;
}
@Bean
public ItemStreamReader<RemittanceVO> reader() {
JdbcPagingItemReader<RemittanceVO> reader = new JdbcPagingItemReader<RemittanceVO>();
reader.setDataSource(dataSource);
reader.setRowMapper(new RemittanceRowMapper());
reader.setQueryProvider(queryProvider);
reader.setPageSize(Constants.SPRING_BATCH_READER_PAGE_SIZE);
return reader;
}
查询提供者 bean,
@Bean
public PagingQueryProvider queryProvider() throws Exception{
SqlPagingQueryProviderFactoryBean queryProviderBean= new SqlPagingQueryProviderFactoryBean();
queryProviderBean.setDataSource(dataSource);
queryProviderBean.setDatabaseType("DB2");
queryProviderBean.setSelectClause(Constants.REMITTANCES_SELECT_CLAUSE);
queryProviderBean.setFromClause(Constants.REMITTANCES_FROM_CLAUSE);
queryProviderBean.setWhereClause(Constants.REMITTANCES_WHERE_CLAUSE);
queryProviderBean.setSortKey(Constants.REMITTANCES_SORT_KEY);
PagingQueryProvider queryProvider = queryProviderBean.getObject();
return queryProvider;
}
【问题讨论】:
-
条件,如果遇到这种情况,
stepExecution.getReadCount() == 0仍然为真,但框架无法识别由Step或Job的侦听器设置或返回的ExitStatus。 -
我的意思是说框架在调试日志中转储的值是相同的——设置或返回不同的值没有影响。比原来的。
-
我也是同样的问题,如果你发现了请更新解决方案
-
@vsr:感谢您的提问。看看我的回答有没有帮助。我记得做过类似的事情,但不是 100% 确定。
标签: spring-batch