当前位置: 首页 > 知识库问答 >
问题:

Spring批处理:不能用不同的作业参数启动作业,也不能访问作业参数

姬裕
2023-03-14

我得和Spring批处理问题。都与通过命令行传入的JobParameters有关。

第一期:

-ts=${current_date} -path="file.csv"
Caused by: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: 
A job instance already exists and is complete for parameters={ts=20210211_1631, path=file.csv}.  
If you want to run this job again, change the parameters.
@Bean(name = "inJob")
public Job inJob(JobRepository jobRepository) {
    return jobBuilderFactory.get("inJob")
            .repository(jobRepository)
            .incrementer(new RunIdIncrementer())
            .start(truncateTable())
            .next(loadCsv())
            .next(updateType())
            .build();
}
@Override
public JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("logging.BATCH_");
    return factory.getObject();
}

@Bean(name = "inReader")
@StepScope
public FlatFileItemReader<CsvInfile> inReader() {       
    FlatFileItemReader<CsvInfile> reader = new FlatFileItemReader<CsvInfile>();
    reader.setResource(new FileSystemResource(path));
    DefaultLineMapper<CsvInfile> lineMapper = new DefaultLineMapper<>();
    lineMapper.setFieldSetMapper(new CsvInfileFieldMapper());
    DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
    tokenizer.setDelimiter("|");
    tokenizer.setNames(ccn.names);
    lineMapper.setLineTokenizer(tokenizer);
    reader.setLineMapper(lineMapper);
    reader.setLinesToSkip(1);
    reader.open(new ExecutionContext());
    return reader;
}

为了从JobParameters获取路径,我使用BeforeStep注释加载JobParameters并将它们复制到局部变量上。不幸的是,这不起作用。变量将为null并且执行失败,因为文件无法打开。

private String path;

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    JobParameters jobParameters = stepExecution.getJobParameters();
    this.path = jobParameters.getString("path");
}

如何访问读取器中的作业参数?我想将文件路径作为命令行参数传入,然后读取这个文件。

共有1个答案

南宫龙野
2023-03-14

第一期:这个问题还有别的解决办法吗?

您的当前日期是每分钟解析一次的,因此,如果在该分钟内运行作业不止一次,则可能已经有一个作业实例具有相同的参数,因此出现了问题。您的ts参数的精度应该是一秒(如果需要,也可以更低)。

第二个问题:如何访问阅读器中的作业参数?我想将文件路径作为命令行参数传入,然后读取这个文件。

@Bean(name = "inReader")
@StepScope
public FlatFileItemReader<CsvInfile> inReader(@Value("#{jobParameters['path']}") String path) {       
    FlatFileItemReader<CsvInfile> reader = new FlatFileItemReader<CsvInfile>();
    reader.setResource(new FileSystemResource(path));
    // ...
    return reader;
}
java -jar myjob.jar path=/absolute/path/to/your/file

参考文档的“作业和步骤属性的后期绑定”部分对此进行了解释。

 类似资料:
  • 我有以下Spring批处理作业配置: 我用以下代码开始这项工作: 如何从作业步骤访问参数?

  • 我有两个不同的工作(实际上更多,但为了简单起见,假设2)。每个作业可以与另一个作业并行运行,但同一作业的每个实例应该顺序运行(否则实例将共享彼此的资源)。 基本上,我希望这些作业中的每一个都有自己的作业实例队列。我想我可以使用两个不同的线程池作业启动程序(每个都有一个线程),并将一个作业启动程序与每个作业相关联。 在从Spring Batch Admin web UI中启动作业时,是否有一种方法可

  • 我配置了一个spring批处理作业,它在spring WebService中运行。这项工作有几个步骤。我已经在不同的tomcats中部署了这个webservice的两个实例(但两个实例都使用相同的mysql数据库)。 我希望用不同的参数在两个tomcats中同时运行spring批处理作业(每个tomcats中一个)。我没有使用分区,每个作业的参数是完全不同的。 我开始工作在一个汤姆猫和一切看起来很

  • 我正在使用Spring batch编写一个批处理,并试图将一个作业参数传递给item reader bean定义,但是当我执行该批处理时,我总是得到以下错误: 我只是不知道我做错了什么,因为根据我在网上发现的文档和其他帖子,一切似乎都很好。 编辑:我使用的是Spring 4.3.3和Spring Batch 3.0.7

  • 我的服务是开始Spring批工作。我希望能够传递一些对象给作业,每次这个对象参数都会不同。这个对象我需要在我的任务中使用。我开始工作的JobLauncher。据我谷歌,我看到JobParameters不会帮助我在这种情况下。此外,我发现很多答案是使用JobExecttionContext或任何东西。但是我想在作业开始前注入参数对象。它是可拥有的吗? 开始工作的服务 我的小任务

  • 我们正在实施Spring批量作业, 我们需要将作业参数从Client/MASTER传递给SLAVE。CLIENT/MASTER是我们的作业和分区代码所在的位置。我们使用传递JOB参数的J Unit调用JOB。 SLAVE是定义所有步骤及其实现(读取器Writer和处理器)的地方。 我们能够以独立的方式实现这一点,但不能与客户一起实现 我们正在使用Weblogic和Spring集成以及JMS来实现同