我有一个长时间运行的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)))" />
感谢。 布赖恩
答案 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)
如果您想终止长时间运行的作业,则有两种方法:
我们可以使用JobInterruptedPolicy以编程方式终止该作业,也可以通过将命令执行到STOP来使用CommandLineRunner手动终止该作业。
JobInterruptionPolicy
使用 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);
如果有jobExceution对象,则可以简单地使用 JobExceution.stop()方法。
以上两种方法都对我成功。
Spring批处理的BATCH_JOB_EXECUTION表
批处理状态:已停止
ExitStatus:已停止