spring batch框架通过元数据表(meta data tables)来保存每个job的执行情况。包括记录每个job的名称和参数,每个job execution的状态和执行结果,每个tasklet的状态和执行结果等。
为了能让JAVA代码访问元数据表,需要做如下配置:
(1)库表准备
假设通过MySQL来存储元数据,需要确保已经安装MySQL,然后创建数据库和初始化元数据表。初始化元数据表的schema可以在spring-batch中找到:
..\spring-batch\spring-batch-core\src\main\resources\org\springframework\batch\core\schema-mysql.sql你可以手动执行这个schema中的sql,也可以通过jdbc:initialize-database进行指定:
<jdbc:initialize-database data-source="dataSource"> <jdbc:script location="clssspath:schema-drop-mysql.sql" /> <jdbc:script location="clssspath:schema-mysql.sql" /> </jdbc:initialize-database>(2)引入MySQL驱动
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>...</version> </dependency>(3)配置JobRepository
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost/spring_batch_test"/> <property name="username" value="root"/> <property name="password" value="1"/> </bean> <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager"/> <property name="databaseType" value="mysql" /> </bean>
通过以上配置后,你的spring batch元数据表就配置好了,当你在运行job时,这些表会得到更新。
spring batch元数据一共有9张表,如下所示:
batch_job_execution batch_job_execution_context batch_job_execution_params batch_job_execution_seq batch_job_instance batch_job_seq batch_step_execution batch_step_execution_context batch_step_execution_seq其中以_seq结尾的三张表,顾名思义维护batch_job_instance、batch_job_execution、batch_step_execution的sequence id。
batch_job_instance表
JOB_INSTANCE_ID:JOB ID由batch_job_seq分配
VERSION:job版本号,同一个job执行多次时使用
JOB_NAME:job名称,与spring配置一致
JOB_KEY:对job参数的MD5编码,正因为有这个字段的存在,同一个job如果第一次运行成功,第二次再运行会抛出JobInstanceAlreadyCompleteException异常。
batch_job_execution_params表:记录每个job的参数
对于如下Parameter:
Map<String, JobParameter> parameterMap = new LinkedHashMap<String, JobParameter>(); parameterMap.put("userId", new JobParameter(8110332L, true)); parameterMap.put("nick", new JobParameter("zhangsan", true)); parameterMap.put("birthday", new JobParameter(new Date(), true));对应的表数据如下:
只有identifying=true的字段才会参与JOB_KEY的MD5编码
batch_job_execution与batch_step_execution表
JOB_EXECUTION_ID:sequence id
VERSION:版本
JOB_INSTANCE_ID:参照batch_job_instance中的JOB_INSTANCE_ID字段
CREATE_TIME
START_TIME
END_TIME
STATUS:job运行的状态
EXIT_CODE:退出码
EXIT_MESSAGE
LAST_UPDATED:最后一次更新时间
JOB_CONFIGURATION_LOCATION
batch_step_execution表除了以上字段外,还有与tasklet相关的一些字段:
COMMIT_COUNT:提交次数
READ_COUNT:读取item数
FILTER_COUNT:被过滤的item数
WRITE_COUNT:写入itemWriter的次数
READ_SKIP_COUNT
WRITE_SKIP_COUNT
PROCESS_SKIP_COUNT
batch_job_execution_context与batch_step_execution_context表
这两张表主要是保存job和step运行中的中间数据, 以便下次运行时可以恢复
STEP_EXECUTION_ID:step id
SHORT_CONTEXT:json化的ExecutionContext,如
{ "map": { "entry": { "string": "FlatFileItemReader.read.count", "int": 10 } } }
SERIALIZED_CONTEXT:被序列化之后的ExecutionContext