設定 JobRepository

如先前所述,JobRepository 用於 Spring Batch 內各種持久化網域物件(例如 JobExecutionStepExecution)的基本 CRUD 操作。許多主要框架功能都需要它,例如 JobLauncherJobStep

  • Java

  • XML

當使用 @EnableBatchProcessing 時,會為您提供 JobRepository。本節說明如何自訂它。Job Repository 的組態選項可以透過 @EnableBatchProcessing 注釋的屬性來指定,如下例所示

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

   // job definition

}

此處列出的組態選項都不是必要的。如果未設定,則會使用先前顯示的預設值。最大 varchar 長度預設為 2500,這是 範例結構描述腳本 中 long VARCHAR 資料行的長度

batch 命名空間抽象化了 JobRepository 實作及其協作者的許多實作細節。但是,仍然有一些組態選項可用,如下例所示

XML 組態
<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 中覆寫隔離等級

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

   // job definition

}

以下範例顯示如何在 XML 中覆寫隔離等級

XML 組態
<job-repository id="jobRepository"
                isolation-level-for-create="REPEATABLE_READ" />

如果未使用命名空間,您還必須使用 AOP 組態 Repository 的交易行為。

  • Java

  • XML

以下範例顯示如何在 Java 中組態 Repository 的交易行為

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 中組態 Repository 的交易行為

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-txspring-aop(或整個 Spring)在類別路徑中。

變更資料表前綴

JobRepository 的另一個可修改屬性是 Metadata 資料表的資料表前綴。預設情況下,它們都以 BATCH_ 作為前綴。BATCH_JOB_EXECUTIONBATCH_STEP_EXECUTION 是兩個範例。但是,可能有一些原因需要修改此前綴。如果結構描述名稱需要前置於資料表名稱,或者如果同一個結構描述中需要多組 Metadata 資料表,則需要變更資料表前綴。

  • Java

  • XML

以下範例顯示如何在 Java 中變更資料表前綴

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

   // job definition

}

以下範例顯示如何在 XML 中變更資料表前綴

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 將資料庫類型設定為最接近的匹配項

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

以下範例顯示如何在 XML 中使用 JobRepositoryFactoryBean 將資料庫類型設定為最接近的匹配項

XML 組態
<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 方式手動連接一個。