元資料 Schema
概述
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 檔案包含用於為許多資料庫平臺建立關係表的示例指令碼(這些平臺反過來由作業倉庫工廠 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 在處理資料庫更新時採用樂觀鎖定策略。這意味著每次“觸及”(更新)記錄時,版本列中的值都會增加一。當倉庫返回儲存值時,如果版本號已更改,它會丟擲 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_INSTANCE_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_INSTANCE_SEQ (ID BIGINT NOT NULL) type=InnoDB;
INSERT INTO BATCH_JOB_INSTANCE_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的序列化,唯一標識同一作業的不同例項。(具有相同作業名稱的JobInstance必須具有不同的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 列的長度加倍就足夠了。其他人更喜歡使用 max-varchar-length 為 VARCHAR 列長度一半的值來配置 JobRepository。一些使用者還報告說,他們在模式定義中使用 NVARCHAR 代替 VARCHAR。最佳結果取決於資料庫平臺以及資料庫伺服器的本地配置方式。
元資料表索引建議
Spring Batch 為核心 jar 檔案中針對幾種常見資料庫平臺的元資料表提供了 DDL 示例。索引宣告不包含在該 DDL 中,因為使用者可能希望如何索引有太多變化,這取決於他們精確的平臺、本地約定以及作業操作的業務需求。下表提供了一些指示,說明哪些列將由 Spring Batch 提供的 DAO 實現用於 WHERE 子句,以及它們可能被使用的頻率,以便各個專案可以自行決定索引
預設表名 |
Where 子句 |
頻率 |
|
|
每次啟動作業時 |
|
|
每次重新啟動作業時 |
|
|
在提交間隔期間,即 chunk(以及步驟的開始和結束時) |
|
|
每次步驟執行前 |