跳到主要内容

配置 JobRepository

QWen Plus 中英对照 Configuring a JobRepository

如前所述,JobRepository 用于在 Spring Batch 中对各种持久化的域对象进行基本的 CRUD 操作,例如 JobExecutionStepExecution。许多主要的框架功能都需要它,例如 JobLauncherJobStep

当使用 @EnableBatchProcessing 时,会为你提供一个 JobRepository。本节描述了如何对其进行自定义。可以通过 @EnableBatchProcessing 注解的属性指定作业存储库的配置选项,如下例所示:

@Configuration
@EnableBatchProcessing(
dataSourceRef = "batchDataSource",
transactionManagerRef = "batchTransactionManager",
tablePrefix = "BATCH_",
maxVarCharLength = 1000,
isolationLevelForCreate = "SERIALIZABLE")
public class MyJobConfiguration {

// 作业定义

}
java

这里列出的配置选项都不是必需的。如果没有设置它们,则使用前面显示的默认值。varchar 的最大长度默认为 2500,这是 示例模式脚本 中长 VARCHAR 列的长度。

作业存储库的事务配置

如果使用了命名空间或提供的 FactoryBean,事务建议会自动围绕存储库创建。这是为了确保批处理元数据(包括失败后重启所需的必要状态)能够正确持久化。如果存储库方法不是事务性的,框架的行为将无法很好地定义。在 create* 方法属性中,隔离级别是单独指定的,以确保在启动作业时,如果有两个进程同时尝试启动同一个作业,只有其中一个能够成功。该方法的默认隔离级别是 SERIALIZABLE,这是一个非常严格的级别。通常,READ_COMMITTED 也能达到相同的效果。如果两个进程不太可能以这种方式发生冲突,READ_UNCOMMITTED 也可以接受。然而,由于调用 create* 方法的时间很短,只要数据库平台支持,SERIALIZED 很少会导致问题。不过,您可以覆盖此设置。

下面的示例展示了如何在 Java 中覆盖隔离级别:

@Configuration
@EnableBatchProcessing(isolationLevelForCreate = "ISOLATION_REPEATABLE_READ")
public class MyJobConfiguration {

// job definition

}
java

如果未使用命名空间,则还必须通过使用 AOP 配置存储库的事务行为。

下面的示例展示了如何在 Java 中配置存储库的事务行为:

@Bean
public TransactionProxyFactoryBean baseProxy() {
TransactionProxyFactoryBean transactionProxyFactoryBean = new TransactionProxyFactoryBean();
Properties transactionAttributes = new Properties();
transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED");
transactionProxyFactoryBean.setTransactionAttributes(transactionAttributes);
transactionProxyFactoryBean.setTarget(jobRepository());
transactionProxyFactoryBean.setTransactionManager(transactionManager());
return transactionProxyFactoryBean;
}
java

更改表前缀

JobRepository 的另一个可修改属性是元数据表的表前缀。默认情况下,所有表都以 BATCH_ 为前缀。BATCH_JOB_EXECUTIONBATCH_STEP_EXECUTION 就是两个例子。然而,修改这个前缀可能存在一些原因。如果需要在表名前添加模式名称,或者在同一模式内需要多组元数据表,则需要更改表前缀。

下面的示例展示了如何在 Java 中更改表前缀:

@Configuration
@EnableBatchProcessing(tablePrefix = "SYSTEM.TEST_")
public class MyJobConfiguration {

// job definition

}
java

鉴于前面的更改,对元数据表的每个查询都以前缀 SYSTEM.TEST_ 开始。BATCH_JOB_EXECUTION 被称为 SYSTEM.TEST_JOB_EXECUTION

备注

仅表前缀是可配置的。表名和列名则不是。

仓库中的非标准数据库类型

如果你使用的数据库平台不在受支持平台的列表中,那么如果 SQL 变体足够接近,你可以使用其中一种受支持的类型。为此,你可以使用原始的 JobRepositoryFactoryBean 而不是命名空间快捷方式,并用它将数据库类型设置为最接近的匹配项。

下面的示例展示了如何使用 JobRepositoryFactoryBean 在 Java 中将数据库类型设置为最接近的匹配项:

@Bean
public JobRepository jobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setDatabaseType("db2");
factory.setTransactionManager(transactionManager);
return factory.getObject();
}
java

如果未指定数据库类型,JobRepositoryFactoryBean 会尝试从 DataSource 自动检测数据库类型。不同平台之间的主要差异主要体现在主键递增策略上,因此通常还需要覆盖 incrementerFactory(通过使用 Spring Framework 提供的标准实现之一)。

如果即使这样也不奏效,或者你没有使用关系型数据库管理系统(RDBMS),那么唯一的选择可能是实现 SimpleJobRepository 所依赖的各种 Dao 接口,并以常规的 Spring 方式手动将其连接起来。