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

Spring Batch:使用不同的参数执行相同的作业

戎兴言
2023-03-14

我是冲刺批次的新手,我找不到问题的答案。

我正在尝试使用Spring引导和Spring批处理实现JOB。我的JOB需要一个参数,所以我像这样执行应用程序:

java-jar-Dspring。配置文件。活动=gus/应用程序/botbit批处理/botbit-batch-1.0.0。jar——Spring。一批工作名称=persistCustomerSuccessMetrics日期=2015年12月13日

粗体是我需要的参数。

我第一次执行应用程序,但在以后的执行中,我的作业总是使用我在第一次执行中传递的参数。

日志显示:

Running default command line with: 
[spring.batch.job.names=persistCustomerSuccessMetrics, date=2015-12-13]

和几行之后:

Job: [FlowJob: [name=persistCustomerSuccessMetrics]] launched with the following parameters: 
[{date=2015-12-12, -spring.batch.job.names=persistCustomerSuccessMetrics, run.id=2}]

日期2015-12-12是第一次执行的日期,我无法使用其他参数再次执行作业。

我的工作设置:

@Bean
@JobScope
public CustomerSuccessMetricsReader customerSuccessMetricsReader(@Value("#{jobParameters[date]}") String date) {
    return new CustomerSuccessMetricsReader(storeStatisticsUrl, restTemplate, date);
}
@Bean
public CustomerSuccessMetricsProcessor customerSuccessMetricsProcessor() {
    return new CustomerSuccessMetricsProcessor();
}
@Bean
public Job persistCustomerSuccessMetrics(Step persistCustomerSuccessMetricsStep1) {
    return jobBuilderFactory.get("persistCustomerSuccessMetrics").incrementer(new RunIdIncrementer())
            .listener(new CustomerSuccessMetricsCompletionListener()).flow(persistCustomerSuccessMetricsStep1).end().build();
}
@Bean
public Step persistCustomerSuccessMetricsStep1() {
    return stepBuilderFactory.
            get("persistCustomerSuccessMetricsStep1").
            <CustomerSuccessMetricsDTO, CustomerSuccessMetricsDTO> chunk(10).
            reader(customerSuccessMetricsReader(null)).
            processor(customerSuccessMetricsProcessor()).
            //writer(customerSuccessMetricsWriter).
            build();
}

我已经尝试删除递增器(new RunIdIncrementer()),在这种情况下,它可以正常工作,但我无法使用相同的参数重复取消执行。

所以,我需要使用以下rqs来实现这项工作:

  • 作业必须采用执行参数,而不是存储在数据库中的参数
  • 作业必须支持具有相同参数的多次执行。

我会感激你的帮助。当做

共有3个答案

黄逸清
2023-03-14

问题是getNexJobParameters是如何工作的。它接受作业的最后一个(!)实例的最后一次执行的JobParameters,并将其作为JobParameter增量输入。这样,通常新实例将继承某种意义上任意作业实例的参数。这显然也包括非标识参数。您可以在命令行上显式覆盖旧参数值。

徐帅
2023-03-14

我已经尝试删除递增器(new RunIdIncrementer()),在这种情况下,它可以正常工作,但我无法使用相同的参数重复取消执行。

按照设计,一旦作业实例完成,就不可能重新运行它(如果您尝试这样做,将引发一个JobInstanceAlreadyCompleteException)。如果上次执行失败,可以重新运行同一实例,但一旦完成,就不能再次运行。下面用一个示例对此进行详细说明:https://docs.spring.io/spring-batch/4.0.x/reference/html/domain.html#jobinstance

作业必须采用执行参数,而不是数据库中存储的参数

该作业必须支持具有相同参数的多次执行。

您可以像现在一样继续使用RunIdIncrementer,但将日期设为非标识参数。这样,运行<代码>。id参数将有助于标识作业实例(因此每次运行都会有一个新实例),但日期参数不会有助于标识作业实例。非标识作业参数应以“-”作为前缀(请参阅DefaultJobParametersConverter的javadoc)。

希望这有帮助。

龙智
2023-03-14

[背景]我也有同样的问题,因为我在命令行上传递的作业只有一个参数,如下所示:

$java-jar/目标/[java可执行jar]。jar文件=[文件路径]

我注意到,在一个全新的spring batch元数据库上,这是第一次正常工作,之后如果我使用不同的文件运行,spring batch将使用存储在batch repository元数据库中的文件路径。

我尝试了上述所有建议的解决方案,但没有一个有效,正如所说的那样。我使用了“.incrementer(new RunIdIncrementer())”,它无法使作业执行唯一。我还尝试将file参数作为非标识参数传递,如下所示:

$java-jar./目标/[java-可执行文件-jar]. jar--file=[文件路径]

我还尝试添加一个时间戳参数,它没有帮助也没有工作。

这似乎是批处理版本中的一个问题,因为根据文档,我能够使作业执行唯一,并使作业使用新文件(文件每次都不同,第一次运行时的文件不同)。

最后,我不得不重新使用黑客技术来强制解决问题,如下所示:

[解决方案]每次运行应用程序时,强制以不同的方式命名作业。这种方式:

@Bean
public Job sampleJob() throws Exception {
   String jobName = "sampleJob" + System.currentTimeMillis();
   return jobBuilderFactory.get(jobName)
      .incrementer(new RunIdIncrementer())
      .start(step1()).on("COMPLETED").to(successFileArchiveStep())
      .from(step1()).on("*").to(failureFileArchiveStep())
      .end()
      .build();
}
 类似资料:
  • 问题内容: 我有一个构建作业和一个测试作业参数。 我想从事构建工作,在并行执行中同时运行一个参数的测试作业和具有不同参数的同一测试作业。 如何做到这一点,以及是否有可能无需编写自己的插件即可执行? 谢谢! 问题答案: 创建测试作业时,将其创建为“构建多配置项目”。在配置作业时,选择“配置矩阵”,然后选择“用户定义的轴” 您可以在作业中将此轴的名称用作参数。给定的参数将在不同的作业中同时启动。(如果

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

  • 问题内容: SQL2008。 我有一个测试表: 我用10k测试行填充它。 我运行以下两个查询: 我不知道为什么这两个查询有不同的执行计划。 查询1确实针对UQ_Sale_RowVersion索引进行索引搜索。 查询2对PK_Sale进行索引扫描。 我想查询2做索引查找。 我将不胜感激。 谢谢你。 [编辑] 尝试使用datetime2而不是rowversion。同样的问题。 我也尝试强制使用索引(查

  • 如果我想创建一个模板类,并根据模板参数的typeid执行不同的操作,那么我该如何编码呢? 例如,我有下面的模板类,我希望在其中初始化成员字段数据,这取决于它是int还是字符串。 但是,这段代码不能用下面的主文件编译。 以及以下主要内容: 我现在得到的链接器错误是:Test template 4.obj:error lnk2019:未解析的外部符号“public:__thiscall A::~A(v

  • 我们在应用程序中使用和。我们的项目通过以下方式创建了RxJava订阅服务器: null 但是,如果不使用参数Subscriber,同时创建一个全新的Subscriber,那么Observable就可以正常工作。 你知道我怎样才能让这件事和参数订阅者一起工作吗?我们希望从活动中调用无法从network service类访问的UI方法onComplete。 这是我的活动代码: 但是这个版本的网络服务类