如何处理长时间运行的 tasklet 期间批处理数据库的防火墙不活动超时



我有一个长时间运行的任务,需要几个小时才能完成。运行批处理作业的框与批处理数据库之间存在防火墙。该防火墙上的不活动超时为两个小时,我们的网络团队不愿意改变这一点。因此,当长时间运行的 tasklet 完成并且 Spring Batch 使用状态更新数据库时,它会失败,因为防火墙已经由于不活动而切断了连接。关于如何解决这个问题的任何想法?

这是我的数据源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin@db_url" />
    <property name="username" value="username" />
    <property name="password" value="password" />
</bean>

更多背景信息。此任务包不使用此数据库连接。只有Spring Batch正在使用它。tasklet 作业是监视队列,并在队列为空后完成下一步。这种队列消耗可能需要数小时。

更新:我尝试添加Oracle TCP保持活动状态,但它仍然超时。

<property name="url" value="jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=port)))(CONNECT_DATA=(SID=sidname)))" />

谢谢。布莱恩

不确定您的tasklet是否真的需要事务,但就我而言,我能够通过定义事务属性来解决问题:

@Bean
public Step myStep(StepBuilderFactory stepBuilderFactory, MyTasklet myTasklet) {
    return stepBuilderFactory.get("myStep").tasklet(myTasklet).transactionAttribute(new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_NEVER)).build();
}

如果你想杀死长时间运行的作业,那么有两种方法:

  1. 作业中断政策
  2. 命令行运行程序

我们可以使用 JobInterruptedPolicy 以编程方式终止作业,也可以使用 CommandLineRunner 手动终止作业,方法是将命令输出到 STOP。

作业中断政策

  1. 使用 JobOperator停止作业

     SimpleJobOperator jobOperator = new SimpleJobOperator();
     jobOperator.setJobRepository(jobRepository);
     jobOperator.setJobLauncher(jobLauncher);
     jobOperator.setJobExplorer(jobExplorer);
     jobOperator.setJobRegistry(jobRegistry);
     //If you know job execution id that you want to stop the job
     jobOperator.stop(exceutionId);
    
  2. 如果你
  3. 有jobExceution对象,你可以简单地使用JobExceution.stop()方法。

以上这两种方法都成功地为我工作。

BATCH_JOB_EXECUTION弹簧批次表

批处理状态:已停止
退出状态:已停止

最新更新