Configuring a JobRepository
如前所述,JobRepository
用于 Spring Batch 中各种持久化域对象的 BASIC CRUD 操作,如 JobExecution
和 StepExecution
。它由许多主要框架特性要求,例如 JobLauncher
、Job
和 Step
。
As described earlier, the JobRepository
is used for basic CRUD operations of the various persisted
domain objects within Spring Batch, such as JobExecution
and StepExecution
.
It is required by many of the major framework features, such as the JobLauncher
,
Job
, and Step
.
- Java
-
使用
@EnableBatchProcessing
时,会为你提供一个JobRepository
。本节介绍如何自定义它。作业存储库的配置选项可以通过@EnableBatchProcessing
注解的属性来指定,如以下范例所示:
When using @EnableBatchProcessing
, a JobRepository
is provided for you.
This section describes how to customize it. Configuration options of the job
repository can be specified through the attributes of the @EnableBatchProcessing
annotation, as shown in the following example:
@Configuration
@EnableBatchProcessing(
dataSourceRef = "batchDataSource",
transactionManagerRef = "batchTransactionManager",
tablePrefix = "BATCH_",
maxVarCharLength = 1000,
isolationLevelForCreate = "SERIALIZABLE")
public class MyJobConfiguration {
// job definition
}
此处列出的配置选项均不是必需的。如果未设置,则使用前面显示的默认值。最大 varchar
长度默认为 2500
,这是 sample schema scripts 中的长 VARCHAR
列的长度
None of the configuration options listed here are required.
If they are not set, the defaults shown earlier are used.
The max varchar
length defaults to 2500
, which is the
length of the long VARCHAR
columns in the
sample schema scripts
- XML
-
批量命名空间抽象了
JobRepository
实现及其实现的许多实现细节。但是,仍然有一些配置选项可用,如下面的范例所示:
The batch namespace abstracts away many of the implementation details of the
JobRepository
implementations and their collaborators. However, there are still a few
configuration options available, as the following example shows:
<job-repository id="jobRepository"
data-source="dataSource"
transaction-manager="transactionManager"
isolation-level-for-create="SERIALIZABLE"
table-prefix="BATCH_"
max-varchar-length="1000"/>
除了 id
之外,前面列出的其他配置选项都不是必需的。如果未设置,则使用前面显示的默认值。max-varchar-length
默认为 2500
,这是 sample schema scripts 中的长 VARCHAR
列的长度。
Other than the id
, none of the configuration options listed earlier are required. If they are
not set, the defaults shown earlier are used.
The max-varchar-length
defaults to 2500
, which is the length of the long
VARCHAR
columns in the sample schema scripts
.
Transaction Configuration for the JobRepository
如果使用命名空间或提供的 FactoryBean
,则会自动在存储库周围创建事务劝告。这是为了确保批处理元数据(包括故障后重新启动所必需的状态)被正确地持久化。如果存储库方法不是事务性的,框架的行为没有明确定义。create*
方法属性中的隔离级别被单独指定,以确保在启动作业时,如果两个进程同时尝试启动同一个作业,则只有其中一个会成功。该方法的默认隔离级别为 SERIALIZABLE
,这是非常激进的。READ_COMMITTED
通常效果一样好。如果两个进程不太可能以这种方式发生冲突,则 READ_UNCOMMITTED
就行了。然而,因为对 create*
方法的调用相当短,只要数据库平台支持它,SERIALIZED
就不太可能引起问题。然而,你可以覆盖此设置。
If the namespace or the provided FactoryBean
is used, transactional advice is
automatically created around the repository. This is to ensure that the batch metadata,
including state that is necessary for restarts after a failure, is persisted correctly.
The behavior of the framework is not well defined if the repository methods are not
transactional. The isolation level in the create*
method attributes is specified
separately to ensure that, when jobs are launched, if two processes try to launch
the same job at the same time, only one succeeds. The default isolation level for that
method is SERIALIZABLE
, which is quite aggressive. READ_COMMITTED
usually works equally
well. READ_UNCOMMITTED
is fine if two processes are not likely to collide in this
way. However, since a call to the create*
method is quite short, it is unlikely that
SERIALIZED
causes problems, as long as the database platform supports it. However, you
can override this setting.
- Java
-
以下范例显示如何在 Java 中覆盖隔离级别:
The following example shows how to override the isolation level in Java:
@Configuration
@EnableBatchProcessing(isolationLevelForCreate = "ISOLATION_REPEATABLE_READ")
public class MyJobConfiguration {
// job definition
}
- XML
-
以下示例显示如何在 XML 中覆盖隔离级别:
The following example shows how to override the isolation level in XML:
<job-repository id="jobRepository"
isolation-level-for-create="REPEATABLE_READ" />
如果未使用命名空间,还必须使用 AOP 来配置存储库的事务行为。
If the namespace is not used, you must also configure the transactional behavior of the repository by using AOP.
- Java
-
以下示例显示如何在 Java 中配置存储库的事务行为:
The following example shows how to configure the transactional behavior of the repository in 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;
}
- XML
-
以下示例显示如何在 XML 中配置存储库的事务行为:
The following example shows how to configure the transactional behavior of the repository in XML:
<aop:config>
<aop:advisor
pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"/>
<advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
你可以几乎按原样使用前面的片段,而几乎无需进行任何更改。另外还要记得包含适当的命名空间声明,并确保 spring-tx
和 spring-aop
(或整个 Spring)在类路径中。
You can use the preceding fragment nearly as is, with almost no changes. Remember also to
include the appropriate namespace declarations and to make sure spring-tx
and spring-aop
(or the whole of Spring) are on the classpath.
Changing the Table Prefix
JobRepository
的其它可修改属性是元数据表的表前缀。默认情况下,它们都以 BATCH_
为前缀。BATCH_JOB_EXECUTION
和 BATCH_STEP_EXECUTION
是两个示例。但是,有一些潜在原因可以修改此前缀。如果架构名称需要添加为表名称的前缀,或者同一个架构内需要多个元数据表集合,则需要更改表前缀。
Another modifiable property of the JobRepository
is the table prefix of the meta-data
tables. By default, they are all prefaced with BATCH_
. BATCH_JOB_EXECUTION
and
BATCH_STEP_EXECUTION
are two examples. However, there are potential reasons to modify this
prefix. If the schema names need to be prepended to the table names or if more than one
set of metadata tables is needed within the same schema, the table prefix needs to
be changed.
- Java
-
以下示例显示如何在 Java 中更改表前缀:
The following example shows how to change the table prefix in Java:
@Configuration
@EnableBatchProcessing(tablePrefix = "SYSTEM.TEST_")
public class MyJobConfiguration {
// job definition
}
- XML
-
以下示例显示如何在 XML 中更改表前缀:
The following example shows how to change the table prefix in XML:
<job-repository id="jobRepository"
table-prefix="SYSTEM.TEST_" />
考虑到上述更改,对元数据表的每个查询都以 SYSTEM.TEST_
为前缀。BATCH_JOB_EXECUTION
被称为 SYSTEM.TEST_JOB_EXECUTION
。
Given the preceding changes, every query to the metadata tables is prefixed with
SYSTEM.TEST_
. BATCH_JOB_EXECUTION
is referred to as SYSTEM.TEST_JOB_EXECUTION
.
只能配置表格前缀。表格和列名是不可配置的。 |
Only the table prefix is configurable. The table and column names are not. |
Non-standard Database Types in a Repository
如果你使用的数据库平台不在受支持的平台列表中,如果你数据库的 SQL 变体足够接近,你可能可以使用其中一个受支持的类型。为此,你可以使用原始 JobRepositoryFactoryBean
而不是命名空间快捷方式,并使用它将数据库类型设置为最接近的匹配项。
If you use a database platform that is not in the list of supported platforms, you
may be able to use one of the supported types, if the SQL variant is close enough. To do
this, you can use the raw JobRepositoryFactoryBean
instead of the namespace shortcut and
use it to set the database type to the closest match.
- Java
-
以下示例显示如何在 Java 中使用
JobRepositoryFactoryBean
将数据库类型设置为最接近的匹配项:
The following example shows how to use JobRepositoryFactoryBean
to set the database type
to the closest match in Java:
@Bean
public JobRepository jobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setDatabaseType("db2");
factory.setTransactionManager(transactionManager);
return factory.getObject();
}
- XML
-
以下示例显示如何在 XML 中使用
JobRepositoryFactoryBean
将数据库类型设置为最接近的匹配项:
The following example shows how to use JobRepositoryFactoryBean
to set the database type
to the closest match in XML:
<bean id="jobRepository" class="org...JobRepositoryFactoryBean">
<property name="databaseType" value="db2"/>
<property name="dataSource" ref="dataSource"/>
</bean>
如果未指定数据库类型,则 JobRepositoryFactoryBean
会尝试从 DataSource
自动检测数据库类型。平台之间的主要区别主要是通过递增主键的策略来考虑的,因此通常还需要覆盖 incrementerFactory
(使用 Spring Framework 中的一个标准实现)。
If the database type is not specified, the JobRepositoryFactoryBean
tries to
auto-detect the database type from the DataSource
.
The major differences between platforms are
mainly accounted for by the strategy for incrementing primary keys, so
it is often necessary to override the
incrementerFactory
as well (by using one of the standard
implementations from the Spring Framework).
如果即使这样还不奏效,或者你没有使用 RDBMS,则唯一的选项可能是实现 SimpleJobRepository
所依赖的各种 Dao
接口,并通过正常的 Spring 方式手动连接一个。
If even that does not work or if you are not using an RDBMS, the
only option may be to implement the various Dao
interfaces that the SimpleJobRepository
depends
on and wire one up manually in the normal Spring way.