我的问题与此existing SO question相反。
JdbcPagingItemReader
的行为似乎与该问题中描述的内容相反,即如果FAILED
找不到任何记录,则作业被标记为JdbcPagingItemReader
。
日志表明作业已标记为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 > ?))
部分。
我的读者豆,
@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;
}
答案 0 :(得分:1)
我无法确定自己是否记得,但我想,我在下面的步骤和工作监听器中做了。
我基本上写了一个StepExecutionListener
并重写了afterStep
方法,如下所示,
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
if (stepExecution.getReadCount() == 0) {
logger.info(
"!!! Step is marked as FAILED because no rows OR no valid rows were read by reader of this step !");
ExitStatus newExitStatus = ExitStatus.COMPLETED;
stepExecution.setExitStatus(newExitStatus);
return newExitStatus;
}
return null;
}
还编写了一个作业级别的侦听器-JobExecutionListenerSupport
,将类似的内容放入重写的afterJob
方法中,
@Override
public void afterJob(JobExecution jobExecution) {
.......
.......
.......
.......
boolean zeroRead = true;
for (StepExecution stepExecution : stepExecutions) {
if (stepExecution.getReadCount() != 0) {
zeroRead = false;
}
}
if (zeroRead) {
logger.info("***** JOB is FAILED because read count is Zero *****");
jobExecution.setExitStatus(ExitStatus.COMPLETED);
return;
}