背景:從資料庫級到會話級的進化
DB2 V8.2 前:唯一透過資料庫配置參數 LOCKTIMEOUT(預設 -1 = 無限等待)統一控制所有應用鎖等待行為。
V8.2+:引入 SET CURRENT LOCK TIMEOUT,允許單一會話覆蓋全域設定,精準適配不同業務需求。
語法與選項完整解析
SET CURRENT LOCK TIMEOUT =
{ WAIT | NOT WAIT | NULL | | }
| 選項 | 行為 | 適用場景 |
WAIT | 無限等待(相當於 -1) | 批次/報表、可容忍長時間阻塞 |
NOT WAIT | 立即返回 SQL0911N rc=68,不等待 | 高並發 OLTP、需快速失敗重試 |
NULL | 使用資料庫級 LOCKTIMEOUT 值 | 回復預設、動態切換 |
n (秒數,0-32767) | 等待 n 秒後返回 SQL0911N rc=68 | 大多數 OLTP 推薦 10-15 秒 |
影響範圍:行鎖、表鎖、索引鍵鎖、MDC 區塊鎖。不影響:表空間鎖、目錄鎖、內部系統鎖。
實戰演示:SAMPLE 資料庫驗證
準備
# 終端機 1
db2 +c "CONNECT TO SAMPLE; CREATE TABLE test(id INT, name CHAR(10)); COMMIT; INSERT INTO test VALUES(1,'test');"
# 未提交,持有 X 鎖
# 終端機 2
db2 +c "CONNECT TO SAMPLE; SELECT * FROM test;"
# 預設 LOCKTIMEOUT=-1 → 無限等待,畫面卡住
套用 NOT WAIT
# 終端機 2 (新連線)
db2 +c "CONNECT TO SAMPLE; SET CURRENT LOCK TIMEOUT NOT WAIT; SELECT * FROM test;"
# 立即報錯:
# SQL0911N The current transaction has been rolled back because of a deadlock
# or timeout. Reason code 68. SQLSTATE=40001
套用 WAIT 10
db2 +c "CONNECT TO SAMPLE; SET CURRENT LOCK TIMEOUT 10; SELECT * FROM test;"
# 等待 10 秒後報相同錯誤
程式化應用:嵌入應用程式與 CLI 配置
嵌入式 SQL / 存儲過程
EXEC SQL SET CURRENT LOCK TIMEOUT = :hv_seconds; -- 主機變數
EXEC SQL SET CURRENT LOCK TIMEOUT NOT WAIT;
CLI/ODBC/JDBC 配置檔
db2cli.ini:
[Common]
LOCKTIMEOUT = WAIT | NOT WAIT | WAIT 15 | 15
- CLI 驅動程式連接時自動發送對應
SET CURRENT LOCK TIMEOUT。
- 應用程式仍可隨時執行 SQL 覆蓋。
設計指南:如何為不同業務選擇策略
| 業務類型 | 建議策略 | 理由 |
| 核心交易 (下單、付款) | WAIT 10-15 | 短暫等待可接受,避免無限阻塞拖垮連接池 |
| 高頻查詢 (商品瀏覽) | NOT WAIT | 快速失敗,應用層重試或降級,保護核心交易資源 |
| 批次報表/ETL | WAIT (或 NULL 繼承長超時) | 可容忍長時間等待,優先保證完成 |
| 管理操作 (DDL、REORG) | WAIT | 需獨佔鎖,等待現有事務提交 |
注意事項
CURRENT LOCK TIMEOUT 專用暫存器隨會話結束自動失效,不持久化。
- 若資料庫級
LOCKTIMEOUT = -1,會話未設定時預設無限等待。
- 死鎖 (
SQL0911N rc=2) 與鎖超時 (rc=68) 錯誤碼不同,應用需分別處理。
- 過度使用
NOT WAIT 可能導致大量重試風暴,需配合應用層退避策略。
- 上一篇文章: 維護 IBM DB2 資料庫必備基礎知識:產品版本、客戶端、通訊協議、授權與版本特性速查
- 下一篇文章: DB2 日常運維實用操作手冊:Load 裝載、應用管理、配置調整、日誌處理與緩衝池調優
Copyright ©
程式碼之家 All Rights Reserved