元資料模式
概述
Spring Batch 元資料表與在 Java 中表示它們的領域物件密切對應。例如,JobInstance
、JobExecution
、JobParameters
和 StepExecution
分別對映到 BATCH_JOB_INSTANCE
、BATCH_JOB_EXECUTION
、BATCH_JOB_EXECUTION_PARAMS
和 BATCH_STEP_EXECUTION
。ExecutionContext
對映到 BATCH_JOB_EXECUTION_CONTEXT
和 BATCH_STEP_EXECUTION_CONTEXT
。JobRepository
負責將每個 Java 物件儲存並存儲到其對應的表中。本附錄詳細描述了元資料表,以及建立它們時所做的許多設計決策。檢視本附錄後面描述的各種表建立語句時,請注意使用的資料型別儘可能通用。Spring Batch 提供了許多模式作為示例。由於各個資料庫供應商處理資料型別的方式不同,所有這些模式的資料型別各不相同。下圖顯示了所有六個表及其相互關係的 ERD 模型

示例 DDL 指令碼
Spring Batch Core JAR 檔案包含用於建立多種資料庫平臺關係表的示例指令碼(這些平臺又會被 job repository factory bean 或等效的名稱空間自動檢測到)。這些指令碼可以按原樣使用,也可以根據需要新增額外的索引和約束進行修改。檔名格式為 schema-*.sql
,其中 *
是目標資料庫平臺的短名稱。這些指令碼位於 org.springframework.batch.core
包中。
遷移 DDL 指令碼
Spring Batch 提供了在升級版本時需要執行的遷移 DDL 指令碼。這些指令碼可以在 Core Jar 檔案的 org/springframework/batch/core/migration
路徑下找到。遷移指令碼按引入的版本號組織到相應的資料夾中
-
2.2
:包含從2.2
之前版本遷移到2.2
版本所需的指令碼 -
4.1
:包含從4.1
之前版本遷移到4.1
版本所需的指令碼
版本
本附錄中討論的許多資料庫表都包含一個版本列。這個列很重要,因為 Spring Batch 在處理資料庫更新時採用了樂觀鎖策略。這意味著每次“觸及”(更新)一條記錄時,版本列中的值都會加一。當 Repository 回去儲存值時,如果版本號已經改變,它會丟擲 OptimisticLockingFailureException
,表示存在併發訪問錯誤。此檢查是必要的,因為即使不同的批處理作業可能在不同的機器上執行,它們都使用相同的資料庫表。
標識
BATCH_JOB_INSTANCE
、BATCH_JOB_EXECUTION
和 BATCH_STEP_EXECUTION
都包含以 _ID
結尾的列。這些欄位作為各自表的主鍵。但是,它們不是資料庫生成的鍵。相反,它們是由單獨的序列生成的。這是必要的,因為將其中一個領域物件插入資料庫後,它獲得的鍵需要設定在實際物件上,以便在 Java 中能夠唯一標識它們。較新的資料庫驅動程式(JDBC 3.0 及以上)支援資料庫生成鍵的此特性。然而,為了不強制要求該特性,使用了序列。每種模式變體都包含以下語句的某種形式
CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
CREATE SEQUENCE BATCH_JOB_SEQ;
許多資料庫供應商不支援序列。在這種情況下,會使用變通方法,例如以下用於 MySQL 的語句
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
CREATE TABLE BATCH_JOB_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_SEQ values(0);
在上述情況下,使用一個表來代替每個序列。然後,Spring 核心類 MySQLMaxValueIncrementer
遞增此序列中的一列以提供類似的功能。
BATCH_JOB_INSTANCE
表
BATCH_JOB_INSTANCE
表儲存了與 JobInstance
相關的所有資訊,並作為整個層次結構的頂部。以下是用於建立它的通用 DDL 語句
CREATE TABLE BATCH_JOB_INSTANCE (
JOB_INSTANCE_ID BIGINT PRIMARY KEY ,
VERSION BIGINT,
JOB_NAME VARCHAR(100) NOT NULL ,
JOB_KEY VARCHAR(32) NOT NULL
);
以下列表描述了表中的每一列
-
JOB_INSTANCE_ID
:唯一標識例項的 ID。它也是主鍵。此列的值應該可以透過呼叫JobInstance
的getId
方法獲得。 -
VERSION
:參見版本。 -
JOB_NAME
:從Job
物件獲取的作業名稱。由於它是標識例項所必需的,因此不能為空。 -
JOB_KEY
:JobParameters
的序列化,用於唯一標識同一作業的不同例項。(具有相同作業名稱的JobInstances
必須具有不同的JobParameters
,因此具有不同的JOB_KEY
值)。
BATCH_JOB_EXECUTION_PARAMS
表
BATCH_JOB_EXECUTION_PARAMS
表儲存了與 JobParameters
物件相關的所有資訊。它包含傳遞給 Job
的 0 個或多個鍵值對,並作為作業執行引數的記錄。對於每個有助於生成作業標識的引數,將 IDENTIFYING
標誌設定為 true。請注意,該表已進行反正規化化。沒有為每種型別建立單獨的表,而是有一個表,其中包含一個指示型別的列,如下所示
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
JOB_EXECUTION_ID BIGINT NOT NULL ,
PARAMETER_NAME VARCHAR(100) NOT NULL ,
PARAMETER_TYPE VARCHAR(100) NOT NULL ,
PARAMETER_VALUE VARCHAR(2500) ,
IDENTIFYING CHAR(1) NOT NULL ,
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
);
以下列表描述了每一列
-
JOB_EXECUTION_ID
:來自BATCH_JOB_EXECUTION
表的外部索引鍵,指示引數條目所屬的作業執行。請注意,每個執行可能存在多行(即鍵值對)。 -
PARAMETER_NAME:引數名稱。
-
PARAMETER_TYPE:引數型別的完全限定名稱。
-
PARAMETER_VALUE:引數值
-
IDENTIFYING:指示引數是否對相關
JobInstance
的標識產生貢獻的標誌。
請注意,此表沒有主鍵。這是因為框架不需要它,因此不強制要求。如果需要,您可以使用資料庫生成的鍵新增主鍵,而不會對框架本身造成任何問題。
BATCH_JOB_EXECUTION
表
BATCH_JOB_EXECUTION
表儲存了與 JobExecution
物件相關的所有資訊。每次執行 Job
時,都會有一個新的 JobExecution
呼叫以及此表中的新行。以下列出了 BATCH_JOB_EXECUTION
表的定義
CREATE TABLE BATCH_JOB_EXECUTION (
JOB_EXECUTION_ID BIGINT PRIMARY KEY ,
VERSION BIGINT,
JOB_INSTANCE_ID BIGINT NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL,
START_TIME TIMESTAMP DEFAULT NULL,
END_TIME TIMESTAMP DEFAULT NULL,
STATUS VARCHAR(10),
EXIT_CODE VARCHAR(20),
EXIT_MESSAGE VARCHAR(2500),
LAST_UPDATED TIMESTAMP,
constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID)
references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ;
以下列表描述了每一列
-
JOB_EXECUTION_ID
:唯一標識此執行的主鍵。此列的值可以透過呼叫JobExecution
物件的getId
方法獲得。 -
VERSION
:參見版本。 -
JOB_INSTANCE_ID
:來自BATCH_JOB_INSTANCE
表的外部索引鍵。它指示此執行所屬的例項。每個例項可能有一個以上的執行。 -
CREATE_TIME
:表示執行建立時間的 timestamp。 -
START_TIME
:表示執行開始時間的 timestamp。 -
END_TIME
:表示執行完成時間的 timestamp,無論成功或失敗。作業當前未執行時此列為空值,表示發生了某種錯誤,並且框架在失敗前未能執行最後一次儲存。 -
STATUS
:表示執行狀態的字串。可以是COMPLETED
、STARTED
等。此列的物件表示是BatchStatus
列舉。 -
EXIT_CODE
:表示執行退出碼的字串。對於命令列作業,這可以轉換為一個數字。 -
EXIT_MESSAGE
:表示作業退出方式更詳細描述的字串。如果失敗,這可能包括儘可能多的堆疊跟蹤資訊。 -
LAST_UPDATED
:表示此執行最後一次持久化時間的 timestamp。
BATCH_STEP_EXECUTION
表
BATCH_STEP_EXECUTION
表儲存了與 StepExecution
物件相關的所有資訊。此表在許多方面與 BATCH_JOB_EXECUTION
表相似,並且每個建立的 JobExecution
針對每個 Step
至少有一個條目。以下列出了 BATCH_STEP_EXECUTION
表的定義
CREATE TABLE BATCH_STEP_EXECUTION (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT NOT NULL,
STEP_NAME VARCHAR(100) NOT NULL,
JOB_EXECUTION_ID BIGINT NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL,
START_TIME TIMESTAMP DEFAULT NULL ,
END_TIME TIMESTAMP DEFAULT NULL,
STATUS VARCHAR(10),
COMMIT_COUNT BIGINT ,
READ_COUNT BIGINT ,
FILTER_COUNT BIGINT ,
WRITE_COUNT BIGINT ,
READ_SKIP_COUNT BIGINT ,
WRITE_SKIP_COUNT BIGINT ,
PROCESS_SKIP_COUNT BIGINT ,
ROLLBACK_COUNT BIGINT ,
EXIT_CODE VARCHAR(20) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED TIMESTAMP,
constraint JOB_EXECUTION_STEP_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;
以下列表描述了每一列
-
STEP_EXECUTION_ID
:唯一標識此執行的主鍵。此列的值應該可以透過呼叫StepExecution
物件的getId
方法獲得。 -
VERSION
:參見版本。 -
STEP_NAME
:此執行所屬步驟的名稱。 -
JOB_EXECUTION_ID
:來自BATCH_JOB_EXECUTION
表的外部索引鍵。它指示此StepExecution
所屬的JobExecution
。對於給定的JobExecution
和給定的Step
名稱,可能只有一個StepExecution
。 -
START_TIME
:表示執行開始時間的 timestamp。 -
END_TIME
:表示執行完成時間的 timestamp,無論成功或失敗。此列為空值(即使作業當前未執行)表示發生了某種錯誤,並且框架在失敗前未能執行最後一次儲存。 -
STATUS
:表示執行狀態的字串。可以是COMPLETED
、STARTED
等。此列的物件表示是BatchStatus
列舉。 -
COMMIT_COUNT
:在此執行期間步驟已提交事務的次數。 -
READ_COUNT
:在此執行期間讀取的專案數。 -
FILTER_COUNT
:在此執行期間被過濾掉的專案數。 -
WRITE_COUNT
:在此執行期間寫入並提交的專案數。 -
READ_SKIP_COUNT
:在此執行期間讀取時跳過的專案數。 -
WRITE_SKIP_COUNT
:在此執行期間寫入時跳過的專案數。 -
PROCESS_SKIP_COUNT
:在此執行期間處理時跳過的專案數。 -
ROLLBACK_COUNT
:在此執行期間回滾的次數。請注意,此計數包括每次發生回滾的次數,包括重試的回滾和跳過恢復過程中的回滾。 -
EXIT_CODE
:表示執行退出碼的字串。對於命令列作業,這可以轉換為一個數字。 -
EXIT_MESSAGE
:表示作業退出方式更詳細描述的字串。如果失敗,這可能包括儘可能多的堆疊跟蹤資訊。 -
LAST_UPDATED
:表示此執行最後一次持久化時間的 timestamp。
BATCH_JOB_EXECUTION_CONTEXT
表
BATCH_JOB_EXECUTION_CONTEXT
表儲存了與 Job
的 ExecutionContext
相關的所有資訊。每個 JobExecution
恰好有一個 Job
ExecutionContext
,它包含特定作業執行所需的所有作業級別資料。此資料通常表示失敗後必須檢索的狀態,以便 JobInstance
可以“從中斷處繼續”。以下列出了 BATCH_JOB_EXECUTION_CONTEXT
表的定義
CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
JOB_EXECUTION_ID BIGINT PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT CLOB,
constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ;
以下列表描述了每一列
-
JOB_EXECUTION_ID
:表示上下文所屬JobExecution
的外部索引鍵。給定執行可能關聯多行。 -
SHORT_CONTEXT
:SERIALIZED_CONTEXT
的字串版本。 -
SERIALIZED_CONTEXT
:整個上下文,序列化後的。
BATCH_STEP_EXECUTION_CONTEXT
表
BATCH_STEP_EXECUTION_CONTEXT
表儲存了與 Step
的 ExecutionContext
相關的所有資訊。每個 StepExecution
恰好有一個 ExecutionContext
,它包含特定步驟執行所需的所有持久化資料。此資料通常表示失敗後必須檢索的狀態,以便 JobInstance
可以“從中斷處繼續”。以下列出了 BATCH_STEP_EXECUTION_CONTEXT
表的定義
CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
STEP_EXECUTION_ID BIGINT PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT CLOB,
constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ;
以下列表描述了每一列
-
STEP_EXECUTION_ID
:表示上下文所屬StepExecution
的外部索引鍵。給定執行可能關聯多行。 -
SHORT_CONTEXT
:SERIALIZED_CONTEXT
的字串版本。 -
SERIALIZED_CONTEXT
:整個上下文,序列化後的。
歸檔
由於每次執行批處理作業時都會在多個表中生成條目,因此通常會為元資料表建立歸檔策略。這些表本身旨在記錄過去發生的事情,並且通常不會影響任何作業的執行,但有一些與重啟相關的顯著例外
-
框架使用元資料表來確定特定的
JobInstance
是否之前執行過。如果執行過並且作業不可重啟,則會丟擲異常。 -
如果刪除了尚未成功完成的
JobInstance
的條目,框架會認為該作業是新作業,而不是重啟。 -
如果作業被重啟,框架會使用持久化到
ExecutionContext
的任何資料來恢復Job
的狀態。因此,刪除此表中尚未成功完成的作業的任何條目,將導致它們再次執行時無法從正確的位置開始。
國際化和多位元組字元
如果您在業務處理中使用多位元組字元集(如中文或西里爾文),這些字元可能需要持久化到 Spring Batch 模式中。許多使用者發現,只需更改模式將 VARCHAR
列的長度加倍就足夠了。其他人則傾向於將 JobRepository 配置為 max-varchar-length
為 VARCHAR
列長度值的一半。還有一些使用者報告說,他們在模式定義中用 NVARCHAR
替換了 VARCHAR
。最佳結果取決於資料庫平臺以及資料庫伺服器在本地的配置方式。
元資料表索引建議
Spring Batch 在核心 jar 檔案中為幾種常見的資料庫平臺提供了元資料表的 DDL 示例。該 DDL 中不包含索引宣告,因為使用者可能希望如何索引有太多差異,取決於其具體的平臺、本地約定以及作業操作的業務需求。下表提供了一些指示,說明 Spring Batch 提供的 DAO 實現將在 WHERE
子句中使用哪些列以及它們可能的使用頻率,以便各個專案可以自行決定索引方式
預設表名 |
Where 子句 |
頻率 |
|
|
每次啟動作業時 |
|
|
每次重啟作業時 |
|
|
在提交間隔,即分塊時(以及步驟開始和結束時) |
|
|
每次步驟執行前 |