Spring Batch_Configuring a Step for Restart

spring官方文档:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html#stepRestart

当一个普通的 job 处于complete 的状态的时候,是不能被restart的。下面看如何使一个job 能够被 restart 。

restartable="true"

<job id="footballJob" restartable="false">
    ...
</job>

首先job应该要配置成 restartable="true"。

然后看step如何配置:

allow-start-if-complete="true"

这是设置当该step完成时,也可以重启。这个默认值是false。

start-limit="3"

这是设置可以重启的次数,默认值是Integer.MAX_VALUE.

这是spring 官方文档给的demo:

<job id="footballJob" restartable="true">
	<step id="playerload" next="gameLoad">
		<tasklet>
			<chunk reader="playerFileItemReader" writer="playerWriter"
				commit-interval="10" />
		</tasklet>
	</step>
	<step id="gameLoad" next="playerSummarization">
		<tasklet allow-start-if-complete="true">
			<chunk reader="gameFileItemReader" writer="gameWriter"
				commit-interval="10" />
		</tasklet>
	</step>
	<step id="playerSummarization">
		<tasklet start-limit="3">
			<chunk reader="playerSummarizationSource" writer="summaryWriter"
				commit-interval="10" />
		</tasklet>
	</step>
</job>

下面是我的关于restart的配置:

spring-batch-restart.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 包的扫描 -->
	<context:component-scan base-package="com.lyx.batch" />

	<bean id="exceptionHandler" class="com.lyx.batch.ExceptionListener" />

	<batch:step id="abstractStep" abstract="true">
		<batch:listeners>
			<batch:listener ref="exceptionHandler" />
		</batch:listeners>
	</batch:step>
	<bean id="abstractCursorReader" abstract="true"
		class="org.springframework.batch.item.database.JdbcCursorItemReader">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- add people desc job begin  -->
	<batch:job id="addPeopleDescJob" restartable="true">
		<batch:step id="addDescStep" parent="abstractStep">
			<batch:tasklet allow-start-if-complete="true"
				start-limit="2">
				<batch:chunk reader="peopleAddDescReader" processor="addDescProcessor"
					writer="addDescPeopleWriter" commit-interval="2" />
			</batch:tasklet>
		</batch:step>
	</batch:job>
	<!-- add people desc job end  -->

	<bean id="peopleAddDescReader" parent="abstractCursorReader"
		scope="step">
		<property name="sql">
			<value><![CDATA[select first_name ,last_name from people where 
			first_name like ? or last_name like ?]]></value>
		</property>
		<property name="rowMapper" ref="peopleRowMapper" />
		<property name="preparedStatementSetter" ref="preparedStatementSetter" />
		<property name="fetchSize" value="20" />
	</bean>
	<bean id="peopleRowMapper" class="com.lyx.batch.PeopleRowMapper" />
	<bean id="preparedStatementSetter" class="com.lyx.batch.PeoplePreparedStatementSetter" />
	<bean id="addDescProcessor" class="com.lyx.batch.AddPeopleDescProcessor" />
	<bean id="addDescPeopleWriter" class="com.lyx.batch.AddDescPeopleWriter" />

	<!--tomcat jdbc pool数据源配置 -->
	<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
		destroy-method="close">
		<property name="poolProperties">
			<bean class="org.apache.tomcat.jdbc.pool.PoolProperties">
				<property name="driverClassName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/test" />
				<property name="username" value="root" />
				<property name="password" value="034039" />
			</bean>
		</property>
	</bean>

	<!-- spring batch 配置jobRepository -->
	<batch:job-repository id="jobRepository"
		data-source="dataSource" transaction-manager="transactionManager"
		isolation-level-for-create="REPEATABLE_READ" table-prefix="BATCH_"
		max-varchar-length="1000" />
	<!-- spring的事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- batch luncher -->
	<bean id="jobLauncher"
		class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
		<property name="jobRepository" ref="jobRepository" />
	</bean>
</beans>

AppMain8.java

package com.lyx.batch;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试restart
 * 
 * @author Lenovo
 *
 */
public class AppMain8 {
	public static void main(String[] args)
			throws JobExecutionAlreadyRunningException, JobRestartException,
			JobInstanceAlreadyCompleteException, JobParametersInvalidException {

		long startTime = System.currentTimeMillis(); // 获取开始时间

		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "classpath:spring-batch-restart.xml" });
		JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
		Job job = (Job) context.getBean("addPeopleDescJob");
		JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
		JobExecution result = launcher.run(job,
				jobParametersBuilder.toJobParameters());
		ExitStatus es = result.getExitStatus();
		if (es.getExitCode().equals(ExitStatus.COMPLETED.getExitCode())) {
			System.out.println("任务正常完成");
		} else {
			System.out.println("任务失败,exitCode=" + es.getExitCode());
		}

		long endTime = System.currentTimeMillis(); // 获取结束时间
		System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
	}

}

当我第一运行成功时:

select * from batch_job_instance;

JOB_INSTANCE_ID  VERSION  JOB_NAME          JOB_KEY                           
---------------  -------  ----------------  --------------------------------  
1                0        addPeopleDescJob  d41d8cd98f00b204e9800998ecf8427e

当我第二次运行成功时,查询一下相关的表:

select * from batch_job_execution;会发现有两个job_execution,都是属于一个job instance。

JOB_INSTANCE_ID  VERSION  JOB_NAME          JOB_KEY                           
---------------  -------  ----------------  --------------------------------  
1                0        addPeopleDescJob  d41d8cd98f00b204e9800998ecf8427e
JOB_EXECUTION_ID  JOB_INSTANCE_ID  CREATE_TIME          
----------------  ---------------  -------------------  
1                 1                2014-11-14 12:33:12  
2                 1                2014-11-14 12:33:48

查看step运行信息:

select STEP_EXECUTION_ID , STEP_NAME , JOB_EXECUTION_ID from batch_step_execution;

STEP_EXECUTION_ID  STEP_NAME    JOB_EXECUTION_ID  
-----------------  -----------  ----------------  
1                  addDescStep  1                 
2                  addDescStep  2

相应的数据库也会多出一倍的数据。

当第三次运行job时,报如下异常信息:

Caused by: org.springframework.batch.core.StartLimitExceededException: Maximum start limit exceeded for step: addDescStepStartMax: 2

很明显,就是重启的次数以用尽。。。

=============================END=============================

时间: 2024-10-20 02:59:27

Spring Batch_Configuring a Step for Restart的相关文章

Spring Batch_Configuring Skip Logic_配置允许抛出的异常

spring 官方文档:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html#configuringSkip 当spring batch 处理过程中,可能要发生错误,就会导致整个批处理过程的失败,而有些错误不应该导致整个批处理的失败,那么通过配置 ???????????? <skippable-exception-classes> ????????????可以忽略掉某些错误,从而使 批处理继续运行.

DEPENDENCY INJECTION EXAMPLE USING SPRING

Dependency Injection The Spring Framework is literally built around the concept of Dependency Injection. In this post, we’ll take a look at a simple example of Dependency Injection using the Spring Framework. If you want a deeper dive on Dependency I

Vim基础教程

一.简介 世界上只有三种编辑器,EMACS.VIM和其它. 我们所处的时代是非常幸运的,有越来越多的编辑器,相对于古老的VIM和EMACS,它们被称为现代编辑器.我们来看看这两个古董有多大年纪了: **EMACS** : 1975 ~ 2013 = 38岁 **VI** : 1976 ~ 2013 = 37岁 **VIM** : 1991 ~ 2013 = 22岁 简单列举一下程序员期望使用的编辑拥有的功能: 轻量级,迅速启动(相对于IDE) 语法高亮 自动对齐 代码折叠 自动补全 显示行号 重

How to install ruby on mac/ change ruby source in china

his one is tailor made for the Basix users among you. If you've been itching to try out Ruby and/or Rails, if the Terminal is somewhat new to you, you may find that even the process of installing it can generate countless confusing errors. This artic

Liunx 环境下vsftpd的三种实现方法(超详细参数)

以下文章介绍Liunx 环境下vsftpd的三种实现方法 ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.0.3.tar.gz,目前已经到2.0.3版本.假设我们已经将vsftpd-2.0.3.tar.gz文件下载到服务器的/home/xuchen目录 代码: # cd /home/xuchen # tar xzvf vsftpd-2.0.3.tar.gz //解压缩程序 # cd vsftpd-2.0.3 三.三种方式的实现            

如何利用闪回数据库特性恢复failover 后的dataguard 环境?

11g dataguard standby 切成主库,测试完成后恢复为原standby 环境 ####################### 概述: 11204 单机对单机实施dg,因局方要求需要(读写模式)打开standby :而这时原生产环境不能有任何影响动,依然对外服务: 采用的思路是:standby 直接failover 为primary db:这时原有dg关系被破坏,互不影响: ####################### 思路概要: 1.确认主库归档日志存放空间是否足够?(需考虑归

SVN – Apache subversion

SVN – Apache subversion SVN – Subversion is a versioning and revision control system used by developers to track and keep up earlier versions of their source codes. In this article we can see how to setup svn server on centos 6. Lets start , Install

【翻译自mos文章】将一个失败的primary database 复原为physical standby 库的步骤

将一个失败的primary database 复原为physical standby 库的步骤 参考自: Step by Step Guide on How To Reinstate Failed Primary Database into Physical Standby (文档 ID 738642.1) 适用于: Oracle Database - Enterprise Edition - Version 10.1.0.2 and later Information in this docu

mesos主机日常操作

清理日志 由于mesos平台日志文件会备份在日志系统内,固主机上的大日志文件可以定时清理. /data/docker/containers -type f -name "*.log" -size +500M   /data/docker/containers目录下.log类型且大于500M的文件可清理 /data/logbak/passport/10.5.0/stress/base -type f -name passport.log.* -size +500M  /data/logb