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

时间:2014-12-12 15:01:03

标签: spring spring-batch

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

这是我的DataSource:

<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>

更多背景资料。此tasklet不使用此数据库连接。只有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)))" />

感谢。 布赖恩

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

如果您想终止长时间运行的作业,则有两种方法:

  1. JobInterruptionPolicy
  2. CommandLineRunner

我们可以使用JobInterruptedPolicy以编程方式终止该作业,也可以通过将命令执行到STOP来使用CommandLineRunner手动终止该作业。

JobInterruptionPolicy

  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. 如果有jobExceution对象,则可以简单地使用 JobExceution.stop()方法。

以上两种方法都对我成功。

Spring批处理的BATCH_JOB_EXECUTION表

批处理状态:已停止
ExitStatus:已停止