Статьи

TaskletStep-ориентированная обработка в Spring Batch

Многие корпоративные приложения требуют пакетной обработки для обработки миллиардов транзакций каждый день. Эти большие наборы транзакций должны обрабатываться без проблем с производительностью. Spring Batch — это легкая и надежная пакетная среда для обработки этих больших наборов данных.

Spring Batch предлагает стиль обработки «TaskletStep Oriented» и «Chunk Oriented». В этой статье описана модель ориентированной обработки TaskletStep.

Давайте исследуем основные компоненты Spring Batch:

Работа:

Сущность, которая инкапсулирует весь пакетный процесс. Шаг и тасклеты определяются в разделе Job

Шаг:

Доменный объект, который инкапсулирует независимую, последовательную фазу пакетного задания.

JobInstance:

Пакетный объект домена, представляющий уникально идентифицируемый запуск задания — его идентичность задается парой Job и JobParameters.

JobParameters:

Объект значения, представляющий параметры времени выполнения для пакетного задания.

JobExecution:

JobExecution относится к технической концепции одной попытки запустить задание. Выполнение может закончиться неудачей или успехом, но JobInstance, соответствующий данному выполнению, не будет считаться завершенным, если выполнение не завершится успешно.

JobRepository:

Интерфейс, который отвечает за сохранность пакетных объектов метаданных. В следующем примере хранилище в памяти используется через MapJobRepositoryFactoryBean.

JobLauncher:

Интерфейс, предоставляющий метод run, который запускает и контролирует определенные задания.

TaskLet:

Интерфейс, предоставляющий метод execute, который будет вызываться повторно до тех пор, пока он не возвратит RepeatStatus.FINISHED или не сгенерирует исключение, чтобы сообщить об ошибке Он используется, когда читатели и писатели не требуются в качестве следующего примера.

Давайте посмотрим, как разработать ориентированную на тасклет модель обработки.

Используемые технологии:

  • JDK 1.7.0_09
  • Весна 3.1.3
  • Весенняя партия 2.1.9
  • Maven 3.0.4

ШАГ 1: СОЗДАТЬ MAVEN ПРОЕКТ

Maven проект создается как показано ниже. (Его можно создать с помощью Maven или IDE Plug-in).

ШАГ 2: БИБЛИОТЕКИ

Во-первых, зависимости добавляются в pom.xml Maven.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<properties>
    <spring.version>3.1.3.RELEASE</spring.version>
    <spring-batch.version>2.1.9.RELEASE</spring-batch.version>
</properties>
 
<dependencies>
    <!-- Spring Dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
 
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>   
 
    <!-- Spring Batch Dependency -->
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-core</artifactId>
        <version>${spring-batch.version}</version>
    </dependency>
 
    <!-- Log4j library -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
 
</dependencies>

maven-compiler-plugin (Maven Plugin) используется для компиляции проекта с JDK 1.7

1
2
3
4
5
6
7
8
9
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.0</version>
    <configuration>
      <source>1.7</source>
      <target>1.7</target>
    </configuration>
</plugin>

Следующий плагин Maven может быть использован для создания runnable-jar ,

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.0</version>
 
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <configuration>
                  <source>1.7</source>
                  <target>1.7</target>
                </configuration>
                <transformers>
                    <transformer
                    implementation=
                          'org.apache.maven.plugins.shade.resource.ManifestResourceTransformer'>
                        <mainClass>com.onlinetechvision.exe.Application</mainClass>
                    </transformer>
                    <transformer
                    implementation=
                                 'org.apache.maven.plugins.shade.resource.AppendingTransformer'>
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer
                    implementation=
                                 'org.apache.maven.plugins.shade.resource.AppendingTransformer'>
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

ШАГ 3: СОЗДАТЬ УСПЕШНЫЙ СТАНДАРТ ТАСКЛЕТ

SuccessfulStepTasklet создается путем реализации интерфейса Tasklet. Это иллюстрирует бизнес-логику в успешном шаге.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.onlinetechvision.tasklet;
 
import org.apache.log4j.Logger;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
 
/**
 * SuccessfulStepTasklet Class illustrates a successful job
 *
 * @author onlinetechvision.com
 * @since 27 Nov 2012
 * @version 1.0.0
 *
 */
public class SuccessfulStepTasklet implements Tasklet {
 
    private static final Logger logger = Logger.getLogger(SuccessfulStepTasklet.class);
 
    private String taskResult;
 
    /**
     * Executes SuccessfulStepTasklet
     *
     * @param StepContribution stepContribution
     * @param ChunkContext chunkContext
     * @return RepeatStatus
     * @throws Exception
     *
     */
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        logger.debug('Task Result : ' + getTaskResult());
        return RepeatStatus.FINISHED;
    }
 
    public String getTaskResult() {
        return taskResult;
    }
 
    public void setTaskResult(String taskResult) {
        this.taskResult = taskResult;
    }
 
}

ШАГ 4: СОЗДАЙТЕ FailedStepTasklet TASKLET

FailedStepTasklet создается путем реализации интерфейса Tasklet. Это иллюстрирует бизнес-логику в неудачном шаге.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.onlinetechvision.tasklet;
 
import org.apache.log4j.Logger;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
 
/**
 * FailedStepTasklet Class illustrates a failed job.
 *
 * @author onlinetechvision.com
 * @since 27 Nov 2012
 * @version 1.0.0
 *
 */
public class FailedStepTasklet implements Tasklet {
 
    private static final Logger logger = Logger.getLogger(FailedStepTasklet.class);
 
    private String taskResult;
 
    /**
     * Executes FailedStepTasklet
     *
     * @param StepContribution stepContribution
     * @param ChunkContext chunkContext
     * @return RepeatStatus
     * @throws Exception
     *
     */
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        logger.debug('Task Result : ' + getTaskResult());
        throw new Exception('Error occurred!');
    }
 
    public String getTaskResult() {
        return taskResult;
    }
 
    public void setTaskResult(String taskResult) {
        this.taskResult = taskResult;
    }
 
}

ШАГ 5: СОЗДАТЬ КЛАСС BatchProcessStarter

Класс BatchProcessStarter создан для запуска заданий. Кроме того, это регистрирует их результаты выполнения. Завершенный экземпляр задания не может быть перезапущен с тем же параметром (ами), поскольку он уже существует в репозитории заданий, а JobInstanceAlreadyCompleteException генерируется с описанием «Экземпляр задания уже существует и завершен». Его можно перезапустить с другим параметром. В следующем примере другой параметр currentTime устанавливается для перезапуска FirstJob.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
package com.onlinetechvision.spring.batch;
 
import org.apache.log4j.Logger;
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.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
 
/**
 * BatchProcessStarter Class launches the jobs and logs their execution results.
 *
 * @author onlinetechvision.com
 * @since 27 Nov 2012
 * @version 1.0.0
 *
 */
public class BatchProcessStarter {
 
    private static final Logger logger = Logger.getLogger(BatchProcessStarter.class);
 
    private Job firstJob;
    private Job secondJob;
    private Job thirdJob;
    private JobLauncher jobLauncher;
    private JobRepository jobRepository;
 
    /**
     * Starts the jobs and logs their execution results.
     *
     */
    public void start() {
        JobExecution jobExecution = null;
        JobParametersBuilder builder = new JobParametersBuilder();
 
        try {
 
            builder.addLong('currentTime', new Long(System.currentTimeMillis()));
            getJobLauncher().run(getFirstJob(), builder.toJobParameters());
            jobExecution = getJobRepository().getLastJobExecution(getFirstJob().getName(), builder.toJobParameters());
            logger.debug(jobExecution.toString());         
 
            getJobLauncher().run(getSecondJob(), builder.toJobParameters());
            jobExecution = getJobRepository().getLastJobExecution(getSecondJob().getName(), builder.toJobParameters());
            logger.debug(jobExecution.toString());
 
            getJobLauncher().run(getThirdJob(), builder.toJobParameters());
            jobExecution = getJobRepository().getLastJobExecution(getThirdJob().getName(), builder.toJobParameters());
            logger.debug(jobExecution.toString());
 
            builder.addLong('currentTime', new Long(System.currentTimeMillis()));
            getJobLauncher().run(getFirstJob(), builder.toJobParameters());
            jobExecution = getJobRepository().getLastJobExecution(getFirstJob().getName(), builder.toJobParameters());
            logger.debug(jobExecution.toString());
 
        } catch (JobExecutionAlreadyRunningException
                    | JobRestartException
                    | JobInstanceAlreadyCompleteException
                    | JobParametersInvalidException e) {
            logger.error(e);
        }
 
    }  
 
    public Job getFirstJob() {
        return firstJob;
    }
 
    public void setFirstJob(Job firstJob) {
        this.firstJob = firstJob;
    }
 
    public Job getSecondJob() {
        return secondJob;
    }
 
    public void setSecondJob(Job secondJob) {
        this.secondJob = secondJob;
    }  
 
    public Job getThirdJob() {
        return thirdJob;
    }
 
    public void setThirdJob(Job thirdJob) {
        this.thirdJob = thirdJob;
    }
 
    public JobLauncher getJobLauncher() {
        return jobLauncher;
    }
 
    public void setJobLauncher(JobLauncher jobLauncher) {
        this.jobLauncher = jobLauncher;
    }
 
    public JobRepository getJobRepository() {
        return jobRepository;
    }
 
    public void setJobRepository(JobRepository jobRepository) {
        this.jobRepository = jobRepository;
    }  
 
}

ШАГ 6: СОЗДАНИЕ applicationContext.xml

Файл конфигурации Spring, applicationContext.xml , создан. Он охватывает определения Tasklets и BatchProcessStarter.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?xml version='1.0' encoding='UTF-8'?>
    xsi:schemaLocation='http://www.springframework.org/schema/beans
 
 
 
 
    <bean id='firstTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='First Task is executed...' />
    </bean>
 
    <bean id='secondTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Second Task is executed...' />
    </bean>
 
    <bean id='thirdTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Third Task is executed...' />
    </bean>
 
    <bean id='fourthTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Fourth Task is executed...' />
    </bean>
 
    <bean id='fifthTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Fifth Task is executed...' />
    </bean>
 
    <bean id='sixthTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Sixth Task is executed...' />
    </bean>
 
     <bean id='seventhTasklet' class='com.onlinetechvision.tasklet.SuccessfulStepTasklet'>
        <property name='taskResult'  value='Seventh Task is executed...' />
    </bean>
 
    <bean id='failedStepTasklet' class='com.onlinetechvision.tasklet.FailedStepTasklet'>
        <property name='taskResult'  value='Error occurred!' />
    </bean>   
 
    <bean id='batchProcessStarter' class='com.onlinetechvision.spring.batch.BatchProcessStarter'>
        <property name='jobLauncher' ref='jobLauncher'/>
        <property name='jobRepository' ref='jobRepository'/>
        <property name='firstJob' ref='firstJob'/>
        <property name='secondJob' ref='secondJob'/>
        <property name='thirdJob' ref='thirdJob'/>
    </bean>   
 
</beans>

ШАГ 7: СОЗДАТЬ jobContext.xml

Файл конфигурации Spring, jobContext.xml , создан. Рабочие потоки следующие:

Поток FirstJob:

1) Первый шаг запущен.
2) После того, как FirstStep завершен со статусом COMPLETED, SecondStep запускается.
3) После завершения SecondStep со статусом COMPLETED запускается ThirdStep.
4) После завершения ThirdStep со статусом COMPLETED выполнение FirstJob завершается со статусом COMPLETED.

Поток SecondJob:

1) Четвертый шаг запущен.
2) После завершения FourthStep со статусом COMPLETED запускается FifthStep.
3) После завершения FifthStep со статусом COMPLETED выполнение SecondJob завершается со статусом COMPLETED.

Поток ThirdJob:

1) Шестой шаг запущен.
2) После завершения SixthStep со статусом COMPLETED запускается SeventhStep.
3) После завершения SeventhStep со статусом FAILED выполнение ThirdJob завершается статусом FAILED.

Поток FirstJob такой же, как и при первом выполнении.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version='1.0' encoding='UTF-8'?>
    xsi:schemaLocation='http://www.springframework.org/schema/beans
 
 
 
 
    <import resource='applicationContext.xml'/>
 
    <bean id='transactionManager' class='org.springframework.batch.support.transaction.ResourcelessTransactionManager'/>
 
    <bean id='jobRepository' class='org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean'>
        <property name='transactionManager' ref='transactionManager' />
    </bean>
 
    <bean id='jobLauncher' class='org.springframework.batch.core.launch.support.SimpleJobLauncher' >
        <property name='jobRepository' ref='jobRepository'/>
    </bean>
 
     <bean id='taskletStep' class='org.springframework.batch.core.step.tasklet.TaskletStep'>
        <property name='jobRepository' ref='jobRepository'/>
        <property name='transactionManager' ref='transactionManager'/>
    </bean>
 
    <batch:job id='firstJob'>
        <batch:step id='firstStep' next='secondStep'>
            <batch:tasklet ref='firstTasklet'/>
        </batch:step>
        <batch:step id='secondStep' next='thirdStep' >
            <batch:tasklet ref='secondTasklet'/>
        </batch:step>
        <batch:step id='thirdStep'>
            <batch:tasklet ref='thirdTasklet' />
        </batch:step>
    </batch:job>
 
    <batch:job id='secondJob'>
        <batch:step id='fourthStep'>
            <batch:tasklet ref='fourthTasklet' />
            <batch:next on='*' to='fifthStep' />
            <batch:next on='FAILED' to='failedStep' />
        </batch:step>
        <batch:step id='fifthStep'>
            <batch:tasklet ref='fifthTasklet' />
        </batch:step>
        <batch:step id='failedStep'>
            <batch:tasklet ref='failedStepTasklet' />
        </batch:step>
    </batch:job>
 
    <batch:job id='thirdJob'>
        <batch:step id='sixthStep'>
            <batch:tasklet ref='sixthTasklet' />
            <batch:next on='*' to='seventhStep' />
            <batch:next on='FAILED' to='eighthStep' />
        </batch:step>
        <batch:step id='seventhStep'>
            <batch:tasklet ref='failedStepTasklet' />
        </batch:step>
        <batch:step id='eighthStep'>
            <batch:tasklet ref='seventhTasklet' />
        </batch:step>
    </batch:job>
 
</beans>

ШАГ 8: СОЗДАЙТЕ КЛАСС ПРИЛОЖЕНИЙ

Класс приложения создан для запуска приложения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.onlinetechvision.exe;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.onlinetechvision.spring.batch.BatchProcessStarter;
 
/**
 * Application Class starts the application.
 *
 * @author onlinetechvision.com
 * @since 27 Nov 2012
 * @version 1.0.0
 *
 */
public class Application {
 
    /**
     * Starts the application
     *
     * @param  String[] args
     *
     */
    public static void main(String[] args) {
        ApplicationContext appContext = new ClassPathXmlApplicationContext('jobContext.xml');
        BatchProcessStarter batchProcessStarter = (BatchProcessStarter)appContext.getBean('batchProcessStarter');
        batchProcessStarter.start();
    }
 
}

ШАГ 9: СТРОИМ ПРОЕКТ

После создания проекта OTV_SpringBatch_TaskletStep_Oriented_Processing будет создан файл OTV_SpringBatch_TaskletStep-0.0.1-SNAPSHOT.jar .

ШАГ 10: ЗАПУСК ПРОЕКТА

После запуска созданного файла OTV_SpringBatch_TaskletStep-0.0.1-SNAPSHOT.jar будут показаны следующие журналы вывода консоли:

Вывод консоли первого задания:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
25.11.2012 21:29:19  INFO (SimpleJobLauncher.java:118) - Job: [FlowJob: [name=firstJob]] launched
with the following parameters: [{currentTime=1353878959462}]
25.11.2012 21:29:19 DEBUG (AbstractJob.java:278) - Job execution starting: JobExecution: id=0, version=0,
startTime=null, endTime=null, lastUpdated=Sun Nov 25 21:29:19 GMT 2012, status=STARTING, exitStatus=exitCode=UNKNOWN;
exitDescription=, job=[JobInstance: id=0, version=0, JobParameters=[{currentTime=1353878959462}], Job=[firstJob]]
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:135) - Resuming state=firstJob.firstStep with status=UNKNOWN
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.firstStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [firstStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=1
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : First Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:209) - Step execution success: id=1
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=1, version=3,
name=firstStep, status=COMPLETED, exitStatus=COMPLETED,
readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.firstStep with status=COMPLETED
 
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.secondStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [secondStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=2
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Second Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:209) - Step execution success: id=2
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=2, version=3,
name=secondStep, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0,
writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.secondStep with status=COMPLETED
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.thirdStep
 
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [thirdStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=3
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Third Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=3, version=3, name=thirdStep,
status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0,
processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.thirdStep with status=COMPLETED
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.end3
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.end3 with status=COMPLETED
25.11.2012 21:29:20 DEBUG (AbstractJob.java:294) - Job execution complete: JobExecution: id=0, version=1, startTime=Sun Nov 25 21:29:19 GMT 2012,
endTime=null, lastUpdated=Sun Nov 25 21:29:19 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=,
job=[JobInstance: id=0, version=0, JobParameters=[{currentTime=1353878959462}], Job=[firstJob]]
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:121) - Job: [FlowJob: [name=firstJob]] completed with the following
parameters: [{currentTime=1353878959462}] and the following status: [COMPLETED]
25.11.2012 21:29:20 DEBUG (BatchProcessStarter.java:44) - JobExecution: id=0, version=2, startTime=Sun Nov 25 21:29:19 GMT 2012,
endTime=Sun Nov 25 21:29:20 GMT 2012, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=,
job=[JobInstance: id=0, version=0, JobParameters=[{currentTime=1353878959462}], Job=[firstJob]]

Вывод консоли второго задания:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:118) - Job: [FlowJob: [name=secondJob]] launched with the following parameters: [{currentTime=1353878959462}]
25.11.2012 21:29:20 DEBUG (AbstractJob.java:278) - Job execution starting: JobExecution: id=1, version=0, startTime=null, endTime=null,
lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=STARTING, exitStatus=exitCode=UNKNOWN;exitDescription=, job=[JobInstance: id=1, version=0,
JobParameters=[{currentTime=1353878959462}], Job=[secondJob]]
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:135) - Resuming state=secondJob.fourthStep with status=UNKNOWN
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=secondJob.fourthStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [fourthStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=4
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Fourth Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=4, version=3, name=fourthStep, status=COMPLETED,
exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=secondJob.fourthStep with status=COMPLETED
 
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=secondJob.fifthStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [fifthStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=5
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Fifth Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=5, version=3, name=fifthStep, status=COMPLETED,
exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=secondJob.fifthStep with status=COMPLETED
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=secondJob.end5
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=secondJob.end5 with status=COMPLETED
25.11.2012 21:29:20 DEBUG (AbstractJob.java:294) - Job execution complete: JobExecution: id=1, version=1, startTime=Sun Nov 25 21:29:20 GMT 2012,
endTime=null, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=, job=[JobInstance: id=1,
version=0, JobParameters=[{currentTime=1353878959462}], Job=[secondJob]]
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:121) - Job: [FlowJob: [name=secondJob]] completed with
the following parameters: [{currentTime=1353878959462}] and the following status: [COMPLETED]
25.11.2012 21:29:20 DEBUG (BatchProcessStarter.java:48) - JobExecution: id=1, version=2, startTime=Sun Nov 25 21:29:20 GMT 2012,
endTime=Sun Nov 25 21:29:20 GMT 2012, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=,
job=[JobInstance: id=1, version=0, JobParameters=[{currentTime=1353878959462}], Job=[secondJob]]

Вывод консоли третьего задания:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:118) - Job: [FlowJob: [name=thirdJob]] launched with the following parameters: [{currentTime=1353878959462}]
25.11.2012 21:29:20 DEBUG (AbstractJob.java:278) - Job execution starting: JobExecution: id=2, version=0, startTime=null, endTime=null,
lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=STARTING, exitStatus=exitCode=UNKNOWN;exitDescription=, job=[JobInstance: id=2, version=0,
JobParameters=[{currentTime=1353878959462}], Job=[thirdJob]]
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:135) - Resuming state=thirdJob.sixthStep with status=UNKNOWN
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=thirdJob.sixthStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [sixthStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=6
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Sixth Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=6, version=3, name=sixthStep, status=COMPLETED,
exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=thirdJob.sixthStep with status=COMPLETED
 
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=thirdJob.seventhStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [seventhStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=7
25.11.2012 21:29:20 DEBUG (FailedStepTasklet.java:33) - Task Result : Error occurred!
25.11.2012 21:29:20 DEBUG (TaskletStep.java:456) - Rollback for Exception: java.lang.Exception: Error occurred!
25.11.2012 21:29:20 DEBUG (TransactionTemplate.java:152) - Initiating transaction rollback on application exception
 
...
 
25.11.2012 21:29:20 DEBUG (AbstractPlatformTransactionManager.java:821) - Initiating transaction rollback
25.11.2012 21:29:20 DEBUG (ResourcelessTransactionManager.java:54) - Rolling back resourceless transaction
on [org.springframework.batch.support.transaction.ResourcelessTransactionManager
$ResourcelessTransaction@40874c04]
25.11.2012 21:29:20 DEBUG (RepeatTemplate.java:291) - Handling exception: java.lang.Exception, caused by: java.lang.Exception: Error occurred!
25.11.2012 21:29:20 DEBUG (RepeatTemplate.java:251) - Handling fatal exception explicitly (rethrowing first of 1): java.lang.Exception: Error occurred!
25.11.2012 21:29:20 ERROR (AbstractStep.java:222) - Encountered an error executing the step
 
...
 
25.11.2012 21:29:20 DEBUG (ResourcelessTransactionManager.java:34) - Committing resourceless transaction on
[org.springframework.batch.support.transaction.ResourcelessTransactionManager
$ResourcelessTransaction@66a7d863]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=7, version=2,
name=seventhStep, status=FAILED, exitStatus=FAILED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0,
writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=1
25.11.2012 21:29:20 DEBUG (ResourcelessTransactionManager.java:34) - Committing resourceless transaction on
[org.springframework.batch.support.transaction.ResourcelessTransactionManager
$ResourcelessTransaction@156f803c]
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=thirdJob.seventhStep with status=FAILED
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=thirdJob.fail8
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=thirdJob.fail8 with status=FAILED
25.11.2012 21:29:20 DEBUG (AbstractJob.java:294) - Job execution complete: JobExecution: id=2, version=1,
startTime=Sun Nov 25 21:29:20 GMT 2012, endTime=null, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=FAILED,
exitStatus=exitCode=FAILED;exitDescription=, job=[JobInstance: id=2, version=0, JobParameters=[{currentTime=1353878959462}], Job=[thirdJob]]
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:121) - Job: [FlowJob: [name=thirdJob]] completed with
the following parameters: [{currentTime=1353878959462}] and the following status: [FAILED]
25.11.2012 21:29:20 DEBUG (BatchProcessStarter.java:52) - JobExecution: id=2, version=2, startTime=Sun Nov 25 21:29:20 GMT 2012,
endTime=Sun Nov 25 21:29:20 GMT 2012, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=FAILED, exitStatus=exitCode=FAILED;
exitDescription=, job=[JobInstance: id=2, version=0, JobParameters=[{currentTime=1353878959462}], Job=[thirdJob]]

Вывод консоли первого задания после перезапуска:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:118) - Job: [FlowJob: [name=firstJob]] launched with the following parameters: [{currentTime=1353878960660}]
25.11.2012 21:29:20 DEBUG (AbstractJob.java:278) - Job execution starting: JobExecution: id=3, version=0, startTime=null,
endTime=null, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=STARTING, exitStatus=exitCode=UNKNOWN;exitDescription=,
job=[JobInstance: id=3, version=0, JobParameters=[{currentTime=1353878960660}], Job=[firstJob]]
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:135) - Resuming state=firstJob.firstStep with status=UNKNOWN
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.firstStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [firstStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=8
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : First Task is executed...
25.11.2012 21:29:20 DEBUG (AbstractStep.java:209) - Step execution success: id=8
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=8, version=3, name=firstStep,
status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.firstStep with status=COMPLETED
 
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.secondStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [secondStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=9
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Second Task is executed...
25.11.2012 21:29:20 DEBUG (TaskletStep.java:417) - Applying contribution: [StepContribution: read=0, written=0, filtered=0,
readSkips=0, writeSkips=0, processSkips=0, exitStatus=EXECUTING]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:209) - Step execution success: id=9
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=9, version=3, name=secondStep,
status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.secondStep with status=COMPLETED
 
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.thirdStep
25.11.2012 21:29:20  INFO (SimpleStepHandler.java:133) - Executing step: [thirdStep]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:180) - Executing: id=10
25.11.2012 21:29:20 DEBUG (SuccessfulStepTasklet.java:33) - Task Result : Third Task is executed...
25.11.2012 21:29:20 DEBUG (TaskletStep.java:417) - Applying contribution: [StepContribution: read=0, written=0, filtered=0,
readSkips=0, writeSkips=0, processSkips=0, exitStatus=EXECUTING]
25.11.2012 21:29:20 DEBUG (AbstractStep.java:209) - Step execution success: id=10
25.11.2012 21:29:20 DEBUG (AbstractStep.java:273) - Step execution complete: StepExecution: id=10, version=3, name=thirdStep,
status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.thirdStep with status=COMPLETED
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:143) - Handling state=firstJob.end3
25.11.2012 21:29:20 DEBUG (SimpleFlow.java:156) - Completed state=firstJob.end3 with status=COMPLETED
25.11.2012 21:29:20 DEBUG (AbstractJob.java:294) - Job execution complete: JobExecution: id=3, version=1, startTime=Sun Nov 25 21:29:20 GMT 2012,
endTime=null, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=, job=[JobInstance: id=3,
version=0, JobParameters=[{currentTime=1353878960660}], Job=[firstJob]]
25.11.2012 21:29:20  INFO (SimpleJobLauncher.java:121) - Job: [FlowJob: [name=firstJob]] completed with
the following parameters: [{currentTime=1353878960660}] and the following status: [COMPLETED]
25.11.2012 21:29:20 DEBUG (BatchProcessStarter.java:57) - JobExecution: id=3, version=2, startTime=Sun Nov 25 21:29:20 GMT 2012,
endTime=Sun Nov 25 21:29:20 GMT 2012, lastUpdated=Sun Nov 25 21:29:20 GMT 2012, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=,
job=[JobInstance: id=3, version=0, JobParameters=[{currentTime=1353878960660}], Job=[firstJob]]

ШАГ 11: СКАЧАТЬ

https://github.com/erenavsarogullari/OTV_SpringBatch_TaskletStep

Ссылки по теме :

Spring Batch — Справочная документация
Spring Batch — Документация по API

Ссылка: TaskletStep Oriented Processing в Spring Batch от нашего партнера JCG Эрен Авсарогуллари в блоге Online Technology Vision .