Spring Batch_Configuring a Step for Restarthtml
spring官方文檔:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html#stepRestartjava
當一個普通的 job 處於complete 的狀態的時候,是不能被restart的。mysql
下面來演示如何使一個job 可以被 restart。spring
<job id="footballJob" restartable="false"> ... </job>
首先job應該要配置成 restartable="true"。而後看step如何配置:sql
這是設置當該step完成時,也能夠重啓。這個默認值是false。數據庫
這是設置能夠重啓的次數,默認值是Integer.MAX_VALUE.apache
這是spring 官方文檔給的demo:tomcat
<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的配置:app
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=================