設定 JobRepository
如先前所述,JobRepository
用於 Spring Batch 內各種持久化網域物件(例如 JobExecution
和 StepExecution
)的基本 CRUD 操作。許多主要框架功能都需要它,例如 JobLauncher
、Job
和 Step
。
-
Java
-
XML
當使用 @EnableBatchProcessing
時,會為您提供 JobRepository
。本節說明如何自訂它。Job Repository 的組態選項可以透過 @EnableBatchProcessing
注釋的屬性來指定,如下例所示
@Configuration
@EnableBatchProcessing(
dataSourceRef = "batchDataSource",
transactionManagerRef = "batchTransactionManager",
tablePrefix = "BATCH_",
maxVarCharLength = 1000,
isolationLevelForCreate = "SERIALIZABLE")
public class MyJobConfiguration {
// job definition
}
此處列出的組態選項都不是必要的。如果未設定,則會使用先前顯示的預設值。最大 varchar
長度預設為 2500
,這是 範例結構描述腳本 中 long VARCHAR
資料行的長度
batch 命名空間抽象化了 JobRepository
實作及其協作者的許多實作細節。但是,仍然有一些組態選項可用,如下例所示
<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
,這是 範例結構描述腳本 中 long VARCHAR
資料行的長度。
JobRepository 的交易組態
如果使用命名空間或提供的 FactoryBean
,則會在 Repository 周圍自動建立交易建議。這是為了確保批次 Metadata(包括失敗後重新啟動所需的狀態)能夠正確地持久化。如果 Repository 方法不是交易性的,則框架的行為未明確定義。create*
方法屬性中的隔離等級是分開指定的,以確保當啟動 Job 時,如果兩個程序嘗試同時啟動相同的 Job,則只有一個程序會成功。該方法的預設隔離等級為 SERIALIZABLE
,這相當激進。READ_COMMITTED
通常也能同樣良好地運作。如果兩個程序不太可能以這種方式衝突,則 READ_UNCOMMITTED
也可以。但是,由於對 create*
方法的呼叫非常短,因此只要資料庫平台支援 SERIALIZED
,就不太可能引起問題。但是,您可以覆寫此設定。
-
Java
-
XML
以下範例顯示如何在 Java 中覆寫隔離等級
@Configuration
@EnableBatchProcessing(isolationLevelForCreate = "ISOLATION_REPEATABLE_READ")
public class MyJobConfiguration {
// job definition
}
以下範例顯示如何在 XML 中覆寫隔離等級
<job-repository id="jobRepository"
isolation-level-for-create="REPEATABLE_READ" />
如果未使用命名空間,您還必須使用 AOP 組態 Repository 的交易行為。
-
Java
-
XML
以下範例顯示如何在 Java 中組態 Repository 的交易行為
@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 中組態 Repository 的交易行為
<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)在類別路徑中。
變更資料表前綴
JobRepository
的另一個可修改屬性是 Metadata 資料表的資料表前綴。預設情況下,它們都以 BATCH_
作為前綴。BATCH_JOB_EXECUTION
和 BATCH_STEP_EXECUTION
是兩個範例。但是,可能有一些原因需要修改此前綴。如果結構描述名稱需要前置於資料表名稱,或者如果同一個結構描述中需要多組 Metadata 資料表,則需要變更資料表前綴。
-
Java
-
XML
以下範例顯示如何在 Java 中變更資料表前綴
@Configuration
@EnableBatchProcessing(tablePrefix = "SYSTEM.TEST_")
public class MyJobConfiguration {
// job definition
}
以下範例顯示如何在 XML 中變更資料表前綴
<job-repository id="jobRepository"
table-prefix="SYSTEM.TEST_" />
給定先前的變更,對 Metadata 資料表的每個查詢都將以 SYSTEM.TEST_
作為前綴。BATCH_JOB_EXECUTION
將稱為 SYSTEM.TEST_JOB_EXECUTION
。
只有資料表前綴是可組態的。資料表和資料行名稱則否。 |
Repository 中的非標準資料庫類型
如果您使用的資料庫平台不在支援平台清單中,則如果 SQL 變體足夠接近,您或許可以使用其中一種支援的類型。若要執行此操作,您可以使用原始的 JobRepositoryFactoryBean
而不是命名空間快捷方式,並使用它將資料庫類型設定為最接近的匹配項。
-
Java
-
XML
以下範例顯示如何在 Java 中使用 JobRepositoryFactoryBean
將資料庫類型設定為最接近的匹配項
@Bean
public JobRepository jobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setDatabaseType("db2");
factory.setTransactionManager(transactionManager);
return factory.getObject();
}
以下範例顯示如何在 XML 中使用 JobRepositoryFactoryBean
將資料庫類型設定為最接近的匹配項
<bean id="jobRepository" class="org...JobRepositoryFactoryBean">
<property name="databaseType" value="db2"/>
<property name="dataSource" ref="dataSource"/>
</bean>
如果未指定資料庫類型,則 JobRepositoryFactoryBean
會嘗試從 DataSource
自動偵測資料庫類型。平台之間的主要差異主要在於遞增主鍵的策略,因此通常也需要覆寫 incrementerFactory
(透過使用 Spring Framework 中的標準實作之一)。
如果即使這樣也不起作用,或者如果您未使用 RDBMS,則唯一的選擇可能是實作 SimpleJobRepository
依賴的各種 Dao
介面,並以正常的 Spring 方式手動連接一個。