H2 數據庫中的事務控制進階與分佈式事務相關關鍵字
在 H2 數據庫的複雜業務場景中,事務控制進階關鍵字能實現更精細的事務管理,分佈式事務相關關鍵字則適配多數據源協同操作需求。這兩類關鍵字覆蓋了單庫事務優化和跨庫數據一致性保障,讓 H2 在複雜業務架構中更具適應性。
一、事務控制進階關鍵字
基礎的BEGIN、COMMIT、ROLLBACK之外,H2 提供了SAVEPOINT、ROLLBACK TO、SET AUTOCOMMIT等進階關鍵字,支持事務部分回滾、自動提交控制等精細化操作,提升事務處理的靈活性。
1. 事務保存點(SAVEPOINT + ROLLBACK TO)
SAVEPOINT用於在事務中創建保存點,ROLLBACK TO可回滾到指定保存點,而非整個事務,適合多步驟事務中僅回滾錯誤步驟的場景。
-- 開啓事務
BEGIN;
-- 第一步:扣減用户餘額
UPDATE users SET balance = balance - 200 WHERE user_id = 1;
-- 創建保存點sp1
SAVEPOINT sp1;
-- 第二步:創建訂單
INSERT INTO orders (user_id, order_no, pay_amount) VALUES (1, 'ORD20240701', 200);
-- 創建保存點sp2
SAVEPOINT sp2;
-- 第三步:扣減商品庫存(假設此處執行失敗)
UPDATE products SET stock = stock - 1 WHERE product_id = 100;
-- 若庫存不足導致第三步失敗,回滾到sp2(僅撤銷庫存扣減,訂單和餘額扣減保留)
ROLLBACK TO sp2;
-- 調整商品ID後重新執行庫存扣減
UPDATE products SET stock = stock - 1 WHERE product_id = 101;
-- 提交事務
COMMIT;
若需撤銷所有操作,可直接ROLLBACK(無保存點參數);若需刪除保存點,用RELEASE SAVEPOINT:
RELEASE SAVEPOINT sp1; -- 刪除保存點sp1,後續無法回滾到該點
2. 自動提交控制(SET AUTOCOMMIT)
SET AUTOCOMMIT用於開啓或關閉自動提交模式,默認情況下 H2 為自動提交(每條 SQL 語句獨立成事務),關閉後需手動COMMIT或ROLLBACK。
-- 關閉自動提交(適合多SQL語句組成一個事務)
SET AUTOCOMMIT OFF;
-- 執行多個操作
UPDATE users SET balance = balance - 100 WHERE user_id = 1;
INSERT INTO orders (user_id, order_no, pay_amount) VALUES (1, 'ORD20240702', 100);
-- 手動提交事務
COMMIT;
-- 重新開啓自動提交(恢復默認行為)
SET AUTOCOMMIT ON;
-- 單條SQL自動提交
INSERT INTO logs (content) VALUES ('用户下單成功');
3. 事務只讀模式(SET TRANSACTION READ ONLY)
SET TRANSACTION READ ONLY將事務設置為只讀模式,數據庫會優化執行計劃(如避免加寫鎖),提升查詢性能,適合報表統計、數據查詢等只讀場景。
-- 開啓只讀事務
SET TRANSACTION READ ONLY;
BEGIN;
-- 執行多個查詢操作(無修改)
SELECT SUM(pay_amount) FROM orders WHERE YEAR(order_time) = 2024;
SELECT category_id, COUNT(*) FROM products GROUP BY category_id;
COMMIT;
4. 事務超時設置(SET TRANSACTION TIMEOUT)
SET TRANSACTION TIMEOUT設置事務執行超時時間(秒),超時後事務自動回滾,避免長時間運行的事務佔用資源。
-- 設置事務超時時間為10秒
SET TRANSACTION TIMEOUT 10;
BEGIN;
-- 執行耗時操作(若超過10秒未提交,自動回滾)
SELECT * FROM large_data_table WHERE create_time < '2023-01-01';
UPDATE orders SET status = '已處理' WHERE order_id IN (SELECT order_id FROM temp_order_ids);
COMMIT;
二、分佈式事務相關關鍵字(適配多數據源場景)
H2 支持通過XA協議實現分佈式事務,核心關鍵字XA START、XA END、XA PREPARE、XA COMMIT、XA ROLLBACK等,用於協調多個數據源的事務一致性,適合跨庫操作場景(如 H2 與 MySQL、Oracle 協同)。
1. XA 事務基礎流程(單數據源 XA 操作)
XA 事務通過 “準備 - 提交” 兩階段確保一致性,以下是 H2 作為 XA 資源的基礎操作:
-- 1. 啓動XA事務(xid為全局事務ID,需唯一)
XA START 'xid_20240701_001';
-- 2. 執行事務操作(如插入訂單)
INSERT INTO orders (user_id, order_no, pay_amount) VALUES (2, 'ORD20240703', 300);
-- 3. 結束XA事務(進入準備階段)
XA END 'xid_20240701_001';
-- 4. 準備階段(確認事務可提交)
XA PREPARE 'xid_20240701_001';
-- 5. 提交事務(所有數據源準備完成後執行)
XA COMMIT 'xid_20240701_001';
-- 若其他數據源準備失敗,回滾XA事務
-- XA ROLLBACK 'xid_20240701_001';
2. 分佈式事務協調(多數據源協同)
假設需要協調 H2 和 MySQL 兩個數據源的事務(以 H2 側操作為例):
-- H2側XA事務操作
XA START 'global_xid_001';
UPDATE h2_orders SET status = '已支付' WHERE order_no = 'ORD20240704';
XA END 'global_xid_001';
XA PREPARE 'global_xid_001'; -- 等待協調器指令
-- (MySQL側執行類似XA準備操作)
-- 若所有數據源準備成功,協調器觸發提交
XA COMMIT 'global_xid_001';
-- 若任一數據源準備失敗,協調器觸發回滾
-- XA ROLLBACK 'global_xid_001';
3. 查看 XA 事務狀態(INFORMATION_SCHEMA.XA_TRANSACTIONS)
通過系統表查詢 XA 事務的狀態,輔助定位分佈式事務問題:
SELECT
XID, -- 全局事務ID
STATE, -- 事務狀態(ACTIVE/IDLE/PREPARED/COMMITTED/ROLLED_BACK)
START_TIME -- 事務啓動時間
FROM INFORMATION_SCHEMA.XA_TRANSACTIONS;
4. 分佈式事務注意事項
-
XID 唯一性:全局事務 ID(XID)需在所有參與數據源中唯一,避免衝突。
-
兩階段提交:必須等待所有數據源XA PREPARE成功後,再執行XA COMMIT,否則會導致數據不一致。
-
資源釋放:事務結束後及時清理 XA 事務殘留,避免資源泄漏。
三、事務相關關鍵字使用原則
-
保存點合理使用:僅在多步驟事務中需要部分回滾時使用SAVEPOINT,過多保存點會增加事務開銷。
-
只讀事務優化:純查詢場景優先設置READ ONLY模式,提升查詢性能。
-
超時控制:針對耗時事務設置TRANSACTION TIMEOUT,避免佔用數據庫連接資源。
-
分佈式事務慎用:XA 事務會降低併發性能,非必要不使用;若需跨庫一致性,優先考慮本地消息表、TCC 等方案,僅在強一致性要求下使用 XA。
這些事務控制進階和分佈式事務相關關鍵字,讓 H2 數據庫的事務管理從 “基礎可用” 升級到 “精細可控”。在多步驟業務、純查詢統計、跨庫協同等場景中,合理運用SAVEPOINT、XA系列關鍵字,能有效提升事務處理靈活性和數據一致性,支撐複雜業務架構的穩定運行。