這很重要
寫入 Unity Catalog 管理的 Delta 資料表的交易都在 公開預覽中。
寫入 Unity Catalog 管理的 Iceberg 表格的交易則在 私人預覽中。 要加入此預覽,請提交 管理的 Iceberg 表格預覽報名表單。
交易讓你能協調跨多個 SQL 語句和資料表的操作。 所有變更必須同時成功或同時回復,確保資料在操作及資料表中一致性。 交易提供 ACID 保證:原子性、一致性、隔離性與耐久性。 請參閱 什麼是 Azure Databricks 上的 ACID 保證?。 交易可搭配 儲存程序 與 SQL 腳本 來建立關鍵任務倉儲工作負載。
以下範例展示了一筆交易:
BEGIN ATOMIC
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
INSERT INTO audit_log VALUES (1, 2, 100, current_timestamp());
END;
這三句話一起承諾。 若任何敘述失敗,所有變更都會回滾,Databricks 也會終止該交易且不會有副作用。
欲實際操作交易,請參考 教學:跨桌協調交易。
要求
要執行涉及多個語句或多個資料表的交易:
- 所有要寫入的資料表必須:
- Be Unity Catalog 管理的資料表(Delta 或 Iceberg)
- 啟用目錄管理的提交
- 使用支援的運算:
交易模式
Azure Databricks 支援兩種交易模式:
| 模式 | 語法 | 承諾 | 回滾 | 最適合用於 |
|---|---|---|---|---|
| 非互動式 | 原子化合物陳述 | 成功時自動 | 錯誤時自動 | 固定序列、排定的工作任務 |
| 互動式 | 開始交易; 承諾; | 說明書 | 說明書 | 條件邏輯、驗證與除錯、JDBC、ODBC、PyDBC |
關於兩種模式的詳細語法、範例及使用模式,請參見 交易模式。
支援的作業
你可以在交易中使用以下操作:
| 運算 | 說明 |
|---|---|
| SELECT | 查詢資料並驗證結果 |
| VALUES 子句 | 產生測試資料或常數值 |
| INSERT (包括所有變體) | 新增列 |
| UPDATE | 修改現有的列 |
COPY INTO |
將檔案資料載入 Delta 表格 |
| DELETE FROM | 移除資料列 |
| MERGE INTO | Upsert 模式結合了插入、更新與刪除 |
在交易中閱讀資料來源
交易可以讀取 Unity Catalog 資料表(Delta 和 Iceberg)、串流資料表、檢視表及具現化檢視表。 要從非交易來源讀取,請使用 allow_nontransactional_reads 提示。
從非交易來源閱讀
若要從非交易來源如 Parquet 檔案、Avro 檔案及 使用 JDBC 的聯邦表格讀取,請使用 allow_nontransactional_reads 提示,如下範例所示:
BEGIN TRANSACTION;
-- Read from a non-transactional Parquet source
INSERT INTO transactional_table
SELECT col1, col2
FROM parquet.`/path/to/data`
WITH (allow_nontransactional_reads = true);
-- Read from a managed Delta table (no hint needed)
INSERT INTO another_table
SELECT * FROM managed_delta_table;
COMMIT;
警告
非交易式讀取無法重複。 交易過程中對來源資料的同時變更可能導致讀取不一致。
交易隔離
交易提供所有語句可重複讀取。 當你在交易中存取資料表時,Azure Databricks 會在首次存取時擷取該資料表的一致快照。 該資料表的所有後續讀取都會使用這個快照,因此即使其他使用者同時修改相同的資料表,讀取結果也會保持一致。
範例:
BEGIN TRANSACTION;
-- First access to products table captures snapshot
SELECT * FROM products WHERE product_id = 1001;
-- Another user updates product 1001
-- Still reads the same snapshot (repeatable read)
SELECT * FROM products WHERE product_id = 1001;
COMMIT;
衝突偵測與並行處理
Azure Databricks 採用樂觀並發控制。 交易可不鎖定,衝突會在提交時偵測到。 當你提交時,Azure Databricks 會檢查其他交易是否在你的交易開始後修改了相同的資料。 如果存在衝突,你的交易就會失敗。 對於非互動式交易,回滾也會自動進行。 對於互動式交易,你必須明確執行 ROLLBACK 以清除交易狀態,才能開始新的交易。
非互動式交易支援列級並行。 當目標資料表啟用列 層級並行 時,兩個交易可以修改同一資料檔中不同的列而不會衝突。
互動式交易支援資料表層級的並行性。
衝突情境
| 情境 | 說明 |
|---|---|
| 寫入衝突 | 兩個交易會更新或刪除相同的資料列。 |
| 寫入-讀取衝突 | 另一筆交易修改了你筆交易讀取的列。 僅適用於可序列化的隔離。 |
| 幻讀問題 | 另一筆交易新增了與你交易讀取的謂詞相符的新列。 適用於可寫序列化(WriteSerializable)與可序列化隔離(Serializable)。 |
| 元資料衝突 | 另一筆交易改變了資料表結構或屬性。 |
關於交易的隔離層級與衝突解決,請參見 交易模式。 關於 Azure Databricks 上 Delta Lake 資料表的隔離層級及寫入衝突行為的資訊,請參閱 Azure Databricks 上的優化建議。
交易在 Delta 日誌中的呈現方式
每筆成功的交易都會以單一條目出現在資料表的 Delta 日誌中,無論在交易中執行了多少個個別語句。 這提供乾淨的稽核軌跡並簡化回滾操作。
交易中的個別操作可作為 JSON 形式的中繼資料在 Delta 日誌中取得。
錯誤處理與回滾
下表說明了兩種交易類型的錯誤回滾如何發生:
| 情境 | 非互動交易的行為 | 互動式交易的行為 |
|---|---|---|
| 陳述句失敗 | 任何引發錯誤的語句都會立即自動回滾。 | 如果會話仍在進行中,必須明確執行 ROLLBACK 來丟棄變更。 |
| 驗證邏輯或商業規則失敗 | 用 SIGNAL 來拋出例外並觸發自動回滾。 |
執行 ROLLBACK 來丟棄變更。 |
| 會話斷線 | 交易會自動回滯。 | 該交易會自動回滾。 |
| 暫停 | 總時長達 48 小時後自動回滾。 | 10分鐘未使用或累計持續時間達到48小時後將自動回復(詳見限制)。 交易會無副作用地終止,但如果會話仍在進行中,你必須明確執行 ROLLBACK 來清除交易狀態。 |
對於交互交易,你可以明確使用 ROLLBACK 陳述式來回復。 當你想根據驗證邏輯或業務規則捨棄變更時,或在敘述失敗且會話仍然活躍時,這很有用。
最佳做法
遵循這些做法以減少衝突並優化交易效能。
避免衝突
- 保持交易時間短:長期交易增加衝突可能性並延長資源保存時間。
- 及早驗證:在交易開始前檢查前提條件,以快速終止可能失敗的操作。
- Databricks 建議大多數使用情境採用非互動式交易:非互動式交易使用列層級並行性。 參見 非互動交易。
- 在衝突時重試:衝突發生時,重新整理資料後重試交易。
使用來自不同客戶的交易
交易在各種客戶端介面間運作:
-
SQL 編輯器與筆記本:在 SQL 儲存格中直接使用
BEGIN ATOMIC ... END;或BEGIN TRANSACTION; ... COMMIT;語法,或在 Python/Scala 筆記本中使用spark.sql()。 請參見 交易模式。 -
JDBC 應用程式:使用 JDBC API 方法(
setAutoCommit(false),commit(),rollback()),搭配 Databricks JDBC 驅動程式 版本 3.0.5 及以上。 參見 使用交易的範例。 關於交易中不支援的 JDBC 操作清單,請參見 不支援的 JDBC 操作。 - ODBC 應用程式:使用 Databricks ODBC 驅動 程式版本 2.10.0 及以上。 關於交易中未支援的 ODBC 操作清單,請參見 不支援的 ODBC 操作。
-
Python 應用程式:使用 Databricks SQL 連接器與
autocommit=False。 請參見 Databricks SQL 連接器的 Python 版本。 關於交易中不支援的 Python 連接器操作清單,請參見 不支援的 Python 連接器操作。 - 語句執行 API:透過 API 呼叫使用 SQL 語法執行交易。 請參見「 使用語句執行 API」。
局限性
以下限制適用於跨多個資料表的交易:
| 限度 | 說明 |
|---|---|
| 互動式交易衝突 | 互動式交易(BEGIN TRANSACTION;... COMMIT;)使用比非互動式交易更保守的衝突偵測,且可以在資料表層級發生衝突,除非是 INSERT 不從目標資料表讀取的操作。 當列層級衝突偵測很重要時,請使用非互動式交易(ATOMIC 複合語句)。 參見 非互動交易。 |
| 寫入目標 | 你只能寫入啟用了catalogManaged表格功能的由Unity Catalog管理的Delta或Iceberg表。 請參見 目錄管理的提交。 |
| 僅限DML營運 | 交易支援 SELECT、INSERT、UPDATE、DELETE、COPY INTO及MERGE。 在交易之外執行 DDL 操作,例如 CREATE TABLE、 ALTER TABLE或 DROP TABLE。 |
| 不支援元資料處理 | 無論通訊協定為何,中繼資料操作都無法在交易中進行。 這包括基於 Thrift RPC 的元資料呼叫(如 JDBC DatabaseMetaData 方法與 ODBC 目錄函式)、基於 SQL 的指令(SHOW TABLES、、SHOW DATABASESDESCRIBE TABLE)以及SELECT對information_schema資料表或系統資料表的查詢。 在交易之外執行元資料操作。 |
COPY INTO 並行性 |
執行指令 COPY INTO 的交易若同時執行另一個 COPY INTO 指令寫入同一資料表並先提交,則該交易失敗。 |
| 不支援串流寫入 | 不支援對串流資料表的交易寫入。 |
| 不支援 RLS 與 CLM 資料表 | 具有 列篩選器和欄位遮罩 的資料表無法參與交易。 |
| 表格與視圖限制 | 一個交易可從最多 100 個資料表讀取或寫入,最多可讀取 100 個視圖。 每個資料表格在交易中最多可有 100 個中間提交記錄。 |
| 不支援時間旅行 | 你不能在交易中使用 時間旅行功能 。 |
| 閒置暫停 | 互動式交易在逾 10 分鐘不活躍後會回復。 交易會無副作用地終止,但如果會話仍在進行中,你必須明確執行 ROLLBACK 來清除交易狀態。 |
| 最長持續時間 | 所有交易會在從開始計算的總時長達到48小時後自動回滾。 對於互動式交易,交易會無副作用地終止,但如果會話仍在進行中,必須明確執行 ROLLBACK 來清除交易狀態。 |
| Delta 共享共享資料表的需求 | Delta 共享服務提供者必須共享一個表格,讓接收者能在該 表格 WITH HISTORY 上執行交易。 接收者可以使用任何類型的運算方式執行交易。 |
| Delta Sharing 接收端的計算限制 | Azure Databricks 的接收者只能在共享檢視、實體化檢視、串流資料表以及非 Iceberg 的外部資料表上執行交易。 與其提供者共用同一 Azure Databricks 帳號的接收者必須使用共享或無伺服器運算。 不同帳號的接收者必須使用無伺服器運算。 |
| Delta 共享來源資料表衝突 | Delta Sharing 的接收者無法在同一筆交易中同時參考同一來源資料表的共享視圖與共用資料表。 |