Spring Batch Item Reader仅执行一次

尝试实现Spring批处理,但遇到一个奇怪的问题,我们的 ItemReader类仅执行一次。

以下是详细信息。

  1. 如果我们在数据库中有1000行。
  2. 我们的项目读取器从数据库中获取1000行,并将列表传递给 ItemWriter
  3. ItemWriter 成功删除所有项目。
  4. 现在,ItemReader再次尝试从数据库获取数据,但是没有找到,因此返回NULL,因此执行停止。
  5. 但是我们已将批处理配置为使用Quartz调度程序执行,即每分钟执行一次。
  6. 现在,如果我们通过转储导入在数据库中插入1000行,那么批处理作业应在下一次执行时选择该数据,尽管JobLauncher执行中它甚至没有

    执行。

-

1.我们有ItemReader,ItemWriter,提交间隔等于1。

<batch:job id="csrfTokenBatchJob">

<batch:step id="step1">

<tasklet>

<chunk reader="csrfTokenReader" writer="csrfTokenWriter" commit-interval="1"></chunk>

</tasklet>

</batch:step>

</batch:job>

2.Job计划每分钟触发一次。

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="triggers">

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">

<property name="jobDetail" ref="jobDetail" />

<property name="cronExpression" value="0 0/1 * * * ?" />

</bean>

</property>

</bean>

3,作业配置

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">

<property name="jobClass" value="com.tavant.oauth.batch.job.CSRFTokenJobLauncher" />

<property name="jobDataAsMap">

<map>

<entry key="jobName" value="csrfTokenCleanUpBatchJob" />

<entry key="jobLocator" value-ref="jobRegistry" />

<entry key="jobLauncher" value-ref="jobLauncher" />

</map>

</property>

</bean>

第一次成功执行,但是后来不执行,但是我可以在日志中看到JobLauncher正在执行。

@Component("csrfTokenReader")

@Scope(value="step")

public class CSRFTokenReader implements ItemReader<List<CSRFToken>> {

private static final Logger logger = LoggerFactory.getLogger(CSRFTokenReader.class);

@Autowired

private CleanService cleanService;

@Override

public List<CSRFToken> read() {

List<CSRFToken> csrfTokenList = null;

try{

int keepUpto = Integer.valueOf(PropertiesContext.getInstance().getProperties().getProperty("token.keep", "1"));

Calendar calTime = Calendar.getInstance();

calTime.add(Calendar.HOUR, -keepUpto);

Date toKeep = calTime.getTime();

csrfTokenList = cleanService.getCSRFTokenByTime(toKeep);

}

catch(Throwable th){

logger.error("Exception in running job At " + new Date() + th);

}

if(CollectionUtils.isEmpty(csrfTokenList)){

return null;

}

return csrfTokenList;

}

}

编辑: -

public class CSRFTokenJobLauncher extends QuartzJobBean {

static final String JOB_NAME = "jobName";

private JobLocator jobLocator;

private JobLauncher jobLauncher;

public void setJobLocator(JobLocator jobLocator) {

this.jobLocator = jobLocator;

}

public void setJobLauncher(JobLauncher jobLauncher) {

this.jobLauncher = jobLauncher;

}

@Override

protected void executeInternal(JobExecutionContext context) {

Map<String, Object> jobDataMap = context.getMergedJobDataMap();

String jobName = (String) jobDataMap.get(JOB_NAME);

log.info("Quartz trigger firing with Spring Batch jobName="+jobName);

JobParameters jobParameters = getJobParametersFromJobMap(jobDataMap);

try {

jobLauncher.run(jobLocator.getJob(jobName), jobParameters);

}

catch (JobExecutionException e) {

log.error("Could not execute job.", e);

}

}

private JobParameters getJobParametersFromJobMap(Map<String, Object> jobDataMap) {

JobParametersBuilder builder = new JobParametersBuilder();

for (Entry<String, Object> entry : jobDataMap.entrySet()) {

String key = entry.getKey();

Object value = entry.getValue();

if (value instanceof String && !key.equals(JOB_NAME)) {

builder.addString(key, (String) value);

}

else if (value instanceof Float || value instanceof Double) {

builder.addDouble(key, ((Number) value).doubleValue());

}

else if (value instanceof Integer || value instanceof Long) {

builder.addLong(key, ((Number)value).longValue());

}

else if (value instanceof Date) {

builder.addDate(key, (Date) value);

}

}

return builder.toJobParameters();

}

}

回答:

经过数小时的时间浪费,问题似乎现在已经解决,我已allow-start-if-

complete="true"在tasklet中进行了配置。现在,批处理项目读取器正在按计划执行。

<batch:job id="csrfTokenBatchJob">

<batch:step id="step1">

<batch:tasklet allow-start-if-complete="true">

<batch:chunk reader="csrfTokenReader" writer="csrfTokenWriter" commit-interval="1"></batch:chunk>

</batch:tasklet>

</batch:step>

</batch:job>

以上是 Spring Batch Item Reader仅执行一次 的全部内容, 来源链接: utcz.com/qa/406459.html

回到顶部