Spring Batch_JOB重启机制

在这一篇文章 对于restart做了试验,http://my.oschina.net/xinxingegeya/blog/344817在这片文章里,我们只是当job成功时,重启了job,对于job失败后,重启job有什么效果,我没有演示,下面我们就来演示一下当job失败退出后,再重启job有什么效果。

先做一个 导致job失败的情景,如下的processor :

ThrowExceptionProcessor.java

package com.lyx.batch;

import org.springframework.batch.item.ItemProcessor;

public class ThrowExceptionProcessor implements

ItemProcessor {

public PeopleDESC process(People item) throws Exception {

System.out.println("process people desc");

if ("lyx".equals(item.getFirstName())) {

throw new InvalidDataException("invalid data");

}

return new PeopleDESC(item.getLastName(), item.getFirstName(), Thread

.currentThread().getName());

}

}

当判断某条数据符合失败条件后,抛出异常 ,导致job失败。

下面是整个配置文件:spring-batch-failure-restart.xml

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

class="org.springframework.batch.item.database.JdbcCursorItemReader">

start-limit="3">

writer="addDescPeopleWriter" commit-interval="2" />

scope="step">

first_name like ? or last_name like ?]]>

destroy-method="close">

data-source="dataSource" transaction-manager="transactionManager"

isolation-level-for-create="REPEATABLE_READ" table-prefix="BATCH_"

max-varchar-length="1000" />

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

class="org.springframework.batch.core.launch.support.SimpleJobLauncher">

运行任务:

AppMain13.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;

/**

* 测试当任务失败时,重启任务

*

* @author Lenovo

*

*/

public class AppMain13 {

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-failure-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");

}

}

第一次运行的结果:

严重: Encountered an error executing step addDescStep in job addPeopleDescJob

com.lyx.batch.InvalidDataException: invalid data

at com.lyx.batch.ThrowExceptionProcessor.process(ThrowExceptionProcessor.java:11)

十一月 19, 2014 4:56:16 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run

信息: Job: [FlowJob: [name=addPeopleDescJob]] completed with the following parameters: [{}] and the following status: [FAILED]

任务失败,exitCode=FAILED

程序运行时间: 7028ms

如上,显示job失败,那么失败的job 在spring batch 的meta table里存储了什么信息:

mysql> select * from batch_step_execution \G

*************************** 1. row ***************************

STEP_EXECUTION_ID: 1

VERSION: 52

STEP_NAME: addDescStep

JOB_EXECUTION_ID: 1

START_TIME: 2014-11-19 16:56:11

END_TIME: 2014-11-19 16:56:16

STATUS: FAILED

COMMIT_COUNT: 50

READ_COUNT: 102

FILTER_COUNT: 0

WRITE_COUNT: 100

READ_SKIP_COUNT: 0

WRITE_SKIP_COUNT: 0

PROCESS_SKIP_COUNT: 0

ROLLBACK_COUNT: 1

EXIT_CODE: FAILED

EXIT_MESSAGE: com.lyx.batch.InvalidDataException: invalid data

at com.lyx.batch.ThrowExceptionProcessor.process(ThrowExceptionProcessor.java:11)

at com.lyx.batch.ThrowExceptionProcessor.process(ThrowExceptionProcessor.java:1)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:126)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.transform(SimpleChunkProcessor.java:293)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:192)

at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)

at o

LAST_UPDATED: 2014-11-19 16:56:16

1 row in set (0.00 sec)

mysql>

这就是step 的运行信息,请注意几个关键的数据,就是

COMMIT_COUNT: 50

READ_COUNT: 102

FILTER_COUNT: 0

WRITE_COUNT: 100

READ_SKIP_COUNT: 0

WRITE_SKIP_COUNT: 0

PROCESS_SKIP_COUNT: 0

ROLLBACK_COUNT: 1

好了,我们先做这些工作,先不去修正会导致异常抛出的数据,我们第二次运行这个job

第二次运行的结果:

信息: Executing step: [addDescStep]

process people desc

十一月 19, 2014 5:03:30 下午 org.springframework.batch.core.step.AbstractStep execute

严重: Encountered an error executing step addDescStep in job addPeopleDescJob

com.lyx.batch.InvalidDataException: invalid data

任务失败,exitCode=FAILED

程序运行时间: 3233ms

十一月 19, 2014 5:03:30 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run

信息: Job: [FlowJob: [name=addPeopleDescJob]] completed with the following parameters: [{}] and the following status: [FAILED]

如上所示,任务失败,再来看一下失败的任务在 spring batch meta table 里存储了什么信息:

mysql> select * from batch_step_execution where step_execution_id = 2 \G

*************************** 1. row ***************************

STEP_EXECUTION_ID: 2

VERSION: 2

STEP_NAME: addDescStep

JOB_EXECUTION_ID: 2

START_TIME: 2014-11-19 17:03:30

END_TIME: 2014-11-19 17:03:30

STATUS: FAILED

COMMIT_COUNT: 0

READ_COUNT: 2

FILTER_COUNT: 0

WRITE_COUNT: 0

READ_SKIP_COUNT: 0

WRITE_SKIP_COUNT: 0

PROCESS_SKIP_COUNT: 0

ROLLBACK_COUNT: 1

EXIT_CODE: FAILED

EXIT_MESSAGE: com.lyx.batch.InvalidDataException: invalid data

at com.lyx.batch.ThrowExceptionProcessor.process(ThrowExceptionProcessor.java:11)

at com.lyx.batch.ThrowExceptionProcessor.process(ThrowExceptionProcessor.java:1)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:126)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.transform(SimpleChunkProcessor.java:293)

at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:192)

at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)

at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)

at o

LAST_UPDATED: 2014-11-19 17:03:30

1 row in set (0.00 sec)

mysql>

要注意这些数据:

COMMIT_COUNT: 0

READ_COUNT: 2

FILTER_COUNT: 0

WRITE_COUNT: 0

READ_SKIP_COUNT: 0

WRITE_SKIP_COUNT: 0

PROCESS_SKIP_COUNT: 0

ROLLBACK_COUNT: 1

看到了没,这里说明了读出来的数据条数为 2 , 除了回滚的次数为 1 外,其他为 0 ;

第三次运行的结果:

在第三次运行前,我们把数据库里的数据修正,再运行

update people set first_name = 'hello',last_name = 'DOE' where first_name = 'lyx';

修正完成,那么第三次运行

信息: Job: [FlowJob: [name=addPeopleDescJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]

任务正常完成

程序运行时间: 3960ms

好的,运行成功了,最重要的就是此时 spring batch在meta table 里存的数据,再来看一下:

mysql> select * from batch_step_execution where step_execution_id = 3 \G

*************************** 1. row ***************************

STEP_EXECUTION_ID: 3

VERSION: 14

STEP_NAME: addDescStep

JOB_EXECUTION_ID: 3

START_TIME: 2014-11-19 17:11:40

END_TIME: 2014-11-19 17:11:42

STATUS: COMPLETED

COMMIT_COUNT: 12

READ_COUNT: 23

FILTER_COUNT: 0

WRITE_COUNT: 23

READ_SKIP_COUNT: 0

WRITE_SKIP_COUNT: 0

PROCESS_SKIP_COUNT: 0

ROLLBACK_COUNT: 0

EXIT_CODE: COMPLETED

EXIT_MESSAGE:

LAST_UPDATED: 2014-11-19 17:11:42

1 row in set (0.00 sec)

mysql>

通过对这三次运行结果的分析,我们可以知道spring batch 对失败的job进行restart ,不是从头开始处理数据,而是从出错的事务边界内第一条记录重复执行的,这样便确保了数据完整性。

当 job 运行成功后(运行成功后也没有必要进行restart),如果 restart 一个job,spring batch就会从第一条记录开始读数据,处理数据,导致数据被重复处理。

batch_step_execution 表字段含义

STEP_EXECUTION_ID: Primary key that uniquely identifies this execution. The value of this column should be obtainable by calling the getId method of the StepExecution object.

VERSION: See above section.

STEP_NAME: The name of the step to which this execution belongs.

JOB_EXECUTION_ID: Foreign key from the BATCH_JOB_EXECUTION table indicating the JobExecution to which this StepExecution belongs. There may be only one StepExecution for a given JobExecution for a given Step name.

START_TIME: Timestamp representing the time the execution was started.

END_TIME: Timestamp representing the time the execution was finished, regardless of success or failure. An empty value in this column even though the job is not currently running indicates that there has been some type of error and the framework was unable to perform a last save before failing.

STATUS: Character string representing the status of the execution. This may be COMPLETED, STARTED, etc. The object representation of this column is the BatchStatus enumeration.

COMMIT_COUNT: The number of times in which the step has committed a transaction during this execution.

READ_COUNT: The number of items read during this execution.

FILTER_COUNT: The number of items filtered out of this execution.‍‍

WRITE_COUNT: The number of items written and committed during this execution.

READ_SKIP_COUNT: The number of items skipped on read during this execution.

WRITE_SKIP_COUNT: The number of items skipped on write during this execution.

PROCESS_SKIP_COUNT: The number of items skipped during processing during this execution.

ROLLBACK_COUNT: The number of rollbacks during this execution. Note that this count includes each time rollback occurs, including rollbacks for retry and those in the skip recovery procedure.

EXIT_CODE: Character string representing the exit code of the execution. In the case of a command line job, this may be converted into a number.

EXIT_MESSAGE: Character string representing a more detailed description of how the job exited. In the case of failure, this might include as much of the stack trace as is possible.

LAST_UPDATED: Timestamp representing the last time this execution was persisted.

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

batch spring 重复执行_Spring Batch_JOB重启机制相关推荐

  1. batch spring 重复执行_Spring源码高级笔记之——Spring AOP应用

    Spring AOP应用 AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往是权限校验代码.日志代码.事务控制代码.性能监控代码. 第1节AOP相关术语 1.1业务主线 在讲解AO ...

  2. batch spring 重复执行_spring-batch – Spring批处理:重新启动作业,然后自动启动下一个作业...

    只是根据incomplete-co.de提供的建议回顾实际完成的工作. 我创建了一个类似于下面的恢复流程.恢复流程包装了我的实际批处理,仅负责为内部作业提供正确的作业参数.它可以是首次执行时的初始参数 ...

  3. batch spring 重复执行_重复的Spring Batch作业实例

    我有一个小的示例Spring Batch应用程序,该应用程序在首次启动时可以正常运行,但是每当我关闭该应用程序并重新启动jar时,我总是会收到此错误: Caused by: org.springfra ...

  4. batch spring 重复执行_可能是最漂亮的Spring事务管理详解

    作者:Guide哥 事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完 ...

  5. batch spring 重复执行_一个3年老javaer竟然连Spring的事务管理都不知道,惊呆了

    1.事务介绍 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 这里我们以取钱的例子来讲解:比如你去ATM ...

  6. java spring 事务传播_spring事务传播机制实例讲解

    天温习spring的事务处理机制,总结如下 对于SQL事务的概念以及ACID性质,可以参见我的另一篇博文 http://kingj.iteye.com/admin/blogs/1675011 spri ...

  7. Spring的quartz定时器重复执行二次的问题解决

    Spring的quartz定时器重复执行二次的问题解决 参考文章: (1)Spring的quartz定时器重复执行二次的问题解决 (2)https://www.cnblogs.com/alamps/p ...

  8. shedlock 重启系统报错问题_闲谈ShedLock解决分布式定时任务重复执行问题

    多个服务实例代码是一样,定时任务自然也一样.负载均衡在执行的时候,到达某个节点以后,定时任务都会执行,可以控制的思路就是使用队列的方式去操作. 现有思路有以下两种:将负载均衡的定时任务,从原先的直接执 ...

  9. 8 -- 深入使用Spring -- 5... Spring 3.1 新增的缓存机制

    8.5 Spring 3.1 新增的缓存机制 Spring 3.1 新增了一种全新的缓存机制,这种缓存机制与Spring容器无缝地整合在一起,可以对容器中的任意Bean或Bean的方法增加缓存.Spr ...

  10. 【Spring学习笔记 九】Spring声明式事务管理实现机制

    什么是事务?事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用,关乎数据准确性的地方我们一定要用到事务,防止业务逻辑出错. 什么是事务管理,事务管理对于企业应用而言至 ...

最新文章

  1. alter system switch logfile与alter system archive log current的区别
  2. 阿里提供中文搜索新选项!AI引擎+达摩院黑科技,你要试试吗?
  3. mysql占用cpu_Mysql占用过高CPU时的优化手段(必看)
  4. 同时开左右两个SAPGUI编辑器显示同一段ABAP代码
  5. 查看命令为内置命令还是外部命令
  6. 图形学教程Lecture 13: RayTracing1(Whitted-Style Ray Tracing)知识点总结
  7. JS学习笔记2-JavaScript 语法
  8. java模块间调用信息_java与c++模块之间的交互方法?
  9. request.getParameterValues与request.getParameter的区别
  10. mybatis缓存查找顺序
  11. keyset与entryset
  12. AppFuse 3.0
  13. 深度学习-自然语言模型
  14. Spring笔记(基于狂神视频+自己理解)
  15. 分享111个HTML医疗保健模板,总有一款适合您
  16. Navicate管理工具的使用
  17. Pandas 时间序列 - DateOffset 对象
  18. 【微信小程序】引入Base64 图标库
  19. 畅玩《七雄争霸》经典战国策略游戏
  20. 之于图片主色调提取算法

热门文章

  1. DNF的SPK文件解析笔记
  2. Wed Sep 16 2020 00:00:00 GMT+0800 (中国标准时间)时间转换为mysql date类型
  3. 项目计划应该怎么样做?看这一篇就够了!
  4. Deepin、统信UOS等Linux系统连接Windows网络邻居的共享文件夹的方法
  5. matlab 数值拉普拉斯变换,数值拉普拉斯变换Python
  6. web 基于jquery和canvas的打飞机小游戏
  7. Vulhub安装过程记录(包括kali快速安装,一个apache中间件漏洞测试)
  8. 7个引人注目的创新物联网应用
  9. 易灵思FPGA烧写EFINIX 芯片下载使用步骤
  10. 离散化-利用计算机求解y=x,离散信号处理(双语)-中国大学mooc-题库零氪