我有一个Spring Batch作业,它通过SFTP从远程Linux服务器检索文件。 远程服务器上的目录是一个包含七天文件(~400个文件)的存档。这些文件的大小相对较小。
Spring Batch知道哪些文件已被处理。
当我启动应用程序时。第一次,Spring Batch tasklet检索文件然后,Spring Batch为它已经处理的每个文件生成一个例外:
E.g。
由以下原因引起:org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException:作业实例已存在,并且对parameters = {input.file.url = file:///blahblahblah.txt}已完成。
这会导致处理过程中的大量延误。
在第一次之后,在随后的sftp检索文件时,没有例外,因此没有延迟(可能是Spring Batch已生成已处理文件的内部哈希列表)。
在Transformer类中,我应该检查文件是否存在于本地,并且仅对尚未处理的新文件调用JobLaunchRequest()?
/ **
将BAI文件转换为Spring Batch作业启动请求 * / public class FileMessageToJobRequestTransformer { public static final Logger LOGGER = LoggerFactory.getLogger(FileMessageToJobRequestTransformer.class); 私人工作;
private String fileParameterName;
public void setJob(Job job){ this.job =工作; }
public void setFileParameterName(String fileParameterName){ LOGGER.debug("文件参数名称:{}",fileParameterName); this.fileParameterName = fileParameterName; }
@Transformer public JobLaunchRequest transform(Message message){ LOGGER.debug("文件消息:{}",message); JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
jobParametersBuilder.addString(fileParameterName,
"file://" + message.getPayload().getAbsolutePath());
LOGGER.debug("Job params: {}", jobParametersBuilder.toJobParameters());
return new JobLaunchRequest(job, jobParametersBuilder.toJobParameters());
} }
有没有办法可以捕捉异常?
JobInstanceAlreadyCompleteException
<!-- When getting a new BAI file, transform into spring batch job request -->
<int:transformer id="fileMessageToJobRequestTransformer"
input-channel="inboundFileChannel"
output-channel="outboundJobRequestChannel"
method="transform">
<bean class="com.distributedfinance.mbi.bai.transformer.FileMessageToJobRequestTransformer">
<property name="job" ref="baiParseJob"/>
<property name="fileParameterName" value="input.file.url"/>
</bean>
<int:poller fixed-rate="10000"/>
</int:transformer>
附加addDate()允许多次处理文件。 现在数据库中有重复数据。
jobParametersBuilder.addString(fileParameterName,
"file://" + message.getPayload().getAbsolutePath())).addDate("rundate", new Date()).toJobParameters();
E.g。
public interface JobExplorer {
List<JobInstance> getJobInstances(String jobName, int start, int count);
JobExecution getJobExecution(Long executionId);
StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId);
JobInstance getJobInstance(Long instanceId);
List<JobExecution> getJobExecutions(JobInstance jobInstance);
Set<JobExecution> findRunningJobExecutions(String jobName);
}
如何捕获异常?
引起:org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException:作业实例已经存在并且已完成参数= {input.file.url = file:/// home / dlaxer / dfc-bank-integration /mbi-application/bai/download/BAI_Intraday160302070054471.txt}。如果要再次运行此作业,请更改参数。 在org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:126) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 在org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) 在org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean $ 1.invoke(AbstractJobRepositoryFactoryBean.java:172) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在com.sun.proxy。$ Proxy113.createJobExecution(未知来源) 在org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:125) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 在org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) 在org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration $ PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在com.sun.proxy。$ Proxy114.run(未知来源) 在org.springframework.batch.integration.launch.JobLaunchingMessageHandler.launch(JobLaunchingMessageHandler.java:50) 在org.springframework.batch.integration.launch.JobLaunchingGateway.handleRequestMessage(JobLaunchingGateway.java:76) ......还有35个
答案 0 :(得分:1)
我看到你在作业启动器中只传递一个参数作为&#34;文件名&#34;。 一旦启动了作业启动器,它将从存储库BATCH_JOB_EXECUTION表中查询并检查上次处理的作业的状态。 在您当前的作业执行输入参数与先前执行的作业相同,批处理状态&amp;退出代码=已完成,然后您将获得JobInstanceAlreadyCompleteException。您应该尝试在每次执行时始终传递唯一的Parmaeters。只需将当前时间作为参数传递并尝试
JobParameters jobparam = new JobParametersBuilder().addString(fileParameterName, "file://" + message.getPayload().getAbsolutePath())
.addDate("rundate", new Date()).toJobParameters();
JobExecution execution = jobLauncher.run(job, jobparam);
catch (Exception e) {
if ( e instanceof JobInstanceAlreadyCompleteException){
System.out.println("Raj*************");
}
2是的,你可以像这样处理
catch(例外e){ if(e instanceof JobInstanceAlreadyCompleteException){ System.out.println(&#34;需要处理*************&#34;); }
答案 1 :(得分:1)
3 - 我应该设置retry-limit =&#34; 1&#34;和skip-limit =&#34; 1&#34;。
回答它取决于您的要求。你要忽略它的异常和次数意味着=跳过限制,并且在吸盘过程中想要重复同一步骤,特殊异常意味着重试。
我们可以用例子更好地理解。如果我想读取一些平面文件,并且文件有可能有错误的输入记录,这可能导致flatFileException
我想忽略它并顺利处理我的文件然后我的配置看起来像这样。
我可以在作业执行期间跳过最多20条记录,如果批次收到异常,任何记录都应该至少尝试2次。
<chunk reader="flatFileItemReader" writer="itemWriter"
commit-interval="1" skip-limit="20" retry-limit="2">
<skippable-exception-classes>
<include class="org.springframework.batch.item.file.FlatFileParseException"/>
</skippable-exception-classes>