首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 9 核心認證指南(第六部分):深度解析數據並發性與一致性控制

     編輯:DB2 教學

前言:為何數據一致性至關重要?

想像一個跨國飯店集團,透過中央資料庫追蹤各分店的番茄醬庫存。當總部調撥 50 瓶從 A 店到 B 店時,系統必須同步完成「A 店扣減 50 瓶」與「B 店新增 50 瓶」兩個動作。若程式只執行前者卻因斷電中斷,總庫存數便會出錯——這就是典型的數據不一致。

在多用戶環境下,同時存取同筆資料更易引發衝突。DB2 內建三大機制保障一致性:事務、隔離級別、鎖。本文將逐層剖析這些核心概念,助你掌握 730 認證考試重點。

事務:資料庫一致性的基石

什麼是事務?

事務(Transaction),又稱工作單元,是將一或多個 SQL 操作封裝成單一可復原序列。其邊界由啟動與終止(COMMIT/ROLLBACK)定義:

  • COMMIT:自事務啟動以來的所有變更永久寫入磁碟
  • ROLLBACK:撤銷所有變更,資料庫還原至事務開始前狀態

無論成功或失敗,DB2 保證事務結束時資料庫處於一致狀態。但開發者仍需確保 SQL 邏輯本身能產生一致結果——資料庫無法自動修正「邏輯上錯誤但語法正確」的操作序列。

實戰範例:COMMIT 與 ROLLBACK 的差異

CONNECT TO MY_DB
CREATE TABLE DEPARTMENT (DEPT_ID INTEGER NOT NULL, DEPT_NAME VARCHAR(20))
INSERT INTO DEPARTMENT VALUES(100, 'PAYROLL')
INSERT INTO DEPARTMENT VALUES(200, 'ACCOUNTING')
COMMIT

INSERT INTO DEPARTMENT VALUES(300, 'SALES')
ROLLBACK

INSERT INTO DEPARTMENT VALUES(500, 'MARKETING')
COMMIT

最終 DEPARTMENT 表僅保留 100、200、500 三筆記錄。第一個 COMMIT 固化前兩筆 INSERT,ROLLBACK 取消第三筆,第二個 COMMIT 確認第四筆。

關鍵特性:未提交的變更對其他用戶不可見(除非使用 Uncommitted Read);一旦提交,便永久可見且不可回滾。

系統故障時的自動復原

若事務執行中途系統崩潰,DB2 會自動回滾所有未提交變更,恢復一致性(前提是事務啟動時資料庫即一致)。下圖對比成功與失敗事務的效果:

成功與不成功事務對比圖

並發挑戰:四大經典現象

多用戶並行存取時,可能發生:

現象說明DB2 預設行為
丟失更新兩事務讀取同一資料並嘗試更新,後者覆蓋前者DB2 架構設計上不允許發生
髒讀讀取未提交的資料,後來該事務回滾可透過隔離級別防止
不可重複讀同一事務兩次讀取同一行,得到不同值(因他人已提交修改/刪除)可透過隔離級別防止
幻像讀重新執行查詢時,發現新增符合條件的行(他人已提交 INSERT)可透過隔離級別防止

四大隔離級別:在一致性與並發間權衡

隔離級別決定「事務 A 存取資料時,如何鎖定/隔離事務 B」。嚴格度由高到低:

1. 可重複讀 — 最嚴格,零容忍

  • 防止:髒讀、不可重複讀、幻像讀
  • 代價:大幅降低並發度
  • 鎖定範圍:事務引用的所有掃描行(非僅擷取行),甚至包含未讀取的間隙
  • 適用場景:大型報表查詢,需保證多次執行結果完全一致

旅館預訂例子:客人掃描可用房間清單期間,經理無法修改該清單內房間價格,其他客人也無法對這些房間訂房/取消,直到該事務結束。但未被掃描的房間不受影響。

可重複讀隔離級別示例

2. 讀穩定性 — 折衷之選

  • 防止:髒讀、不可重複讀
  • 允許:幻像讀
  • 鎖定範圍:僅實際擷取/修改的行
  • 適用場景:需一定並發度,但要求已讀取資料在事務期間穩定

旅館例子:客人查詢可用房間後,經理可修改清單外房價;其他客人可訂房/取消。若客人重跑查詢,可能看到新房間或價格變動。

讀穩定性隔離級別示例

3. 游標穩定性 — DB2 預設級別

  • 防止:髒讀
  • 允許:不可重複讀、幻像讀
  • 鎖定範圍:僅游標當前指向的行
  • 適用場景:追求最大並發,且不介意重讀時資料可能已變

旅館例子:客人逐筆瀏覽房間詳情時,僅「當前正看的那間」被鎖定;換下一間時,前一間立即釋放鎖定。

游標穩定性隔離級別示例

4. 未提交的讀 — 最寬鬆,效能最佳

  • 允許:髒讀、不可重複讀、幻像讀
  • 鎖定策略:幾乎不加鎖,僅防止 DDL 操作(如 DROP TABLE)
  • 適用場景:唯讀報表、不介意臟資料的查詢

旅館例子:客人看到的清單可能包含「正被他人訂房中」的房間;經理可隨時改價,不受任何查詢阻擋。

未提交的讀隔離級別示例

如何選擇正確的隔離級別?

依據不可接受的現象反推:

  • 完全不能接受幻像/不可重複讀 → Repeatable Read
  • 可接受幻像,但要已讀資料穩定 → Read Stability
  • 要最大並發,只拒絕髒讀 → Cursor Stability(預設)
  • 唯讀或不介意髒資料 → Uncommitted Read

指定隔離級別的多種方式

應用類型指定方式
嵌入式 SQLPRECOMPILE/BIND 時用 ISOLATION 選項
ODBC/CLI執行時呼叫 SQLSetConnectAttr(SQL_ATTR_TXN_ISOLATION) 或設 db2cli.ini 的 TXNISOLATION
JDBC/SQLJ執行時呼叫 setTransactionIsolation()
CLP 腳本連線前執行 CHANGE ISOLATION 命令
單一查詢SELECT ... WITH [RR|RS|CS|UR] 子句(DB2 UDB 8.1+)

最後一種「查詢級指定」極具彈性:主程式用 CS 追求並發,關鍵報表查詢單獨加 WITH RR 確保一致性。

鎖機制:並發控制的底層引擎

鎖的四大屬性

  • Object:鎖定資源類型(表空間、表、行)
  • Size:粒度(行級 vs 表級)
  • Duration:持有時間(由隔離級別決定)
  • Mode:鎖模式/狀態(決定兼容性)

11 種鎖模式(由弱到強)

模式適用對象核心語意
IN (Intent None)表空間、表可讀(含未提交),不加行鎖,他人可讀寫
IS (Intent Share)表空間、表可讀,不加行鎖,他人可讀寫;讀取行時加 S 鎖
NS (Next Key Share)行RS/CS 級別下替代 S 鎖,可讀不可改
S (Share)表、行可讀不可改,他人可讀不可改
IX (Intent Exclusive)表空間、表可讀寫,讀取行加 S,更新行加 U/X;他人可讀寫
SIX (Share With Intent Exclusive)表可讀寫,更新行加 X,讀取行不加鎖;他人可讀不可改
U (Update)表、行可更新,自動升級為 X;他人可讀不可改
NW (Next Key Weak Exclusive)行非編目索引插入時,對下一行加此鎖
X (Exclusive)表、行可讀寫,僅 UR 級別可存取;INSERT/UPDATE/DELETE 會取得
WE (Weak Exclusive)行非編目表插入行時加此鎖
Z (Super Exclusive)表空間、表DDL 操作(ALTER/DROP/CREATE INDEX)自動取得,獨佔全表

鎖獲取邏輯與手動控制

DB2 傾向隱式獲取行級鎖。可透過:

  • ALTER TABLE t LOCKSIZE TABLE — 強制該表所有事務用表級鎖
  • LOCK TABLE t IN SHARE|EXCLUSIVE MODE — 單一事務主動請求表級鎖

鎖升級:當鎖記憶體不足(受 maxlocks 限制),自動將多個行鎖合併為單一表鎖,釋放空間。

效能三大議題:兼容性、轉換、升級

  • 兼容性:兩鎖能否共存?DB2 依模式表判斷,不兼容則等待(鎖等待事件)
  • 轉換:同一事務同一資源需更強鎖時,升級現有鎖(如 S→X,IX+S→SIX)
  • 升級:行鎖過多時自動轉為表鎖,降低並發但節省記憶體

鎖超時與死鎖處理

  • locktimeout 參數:設定等待上限,超時回滾事務,防止無限期阻塞
  • 死鎖偵測器:背景程式定期掃描,發現循環等待隨機犧牲一事務(回滾並釋放鎖)打破死結
死鎖循環示意圖

鎖粒度選擇策略

  • 行級鎖:並發度高,但每鎖需記憶體/CPU 開銷
  • 表級鎖:開銷低,適合大量資料修改或唯讀大表掃描
  • 透過 ALTER TABLE ... LOCKSIZE ROW/TABLE 與 LOCK TABLE 靈活控制

事務類型與存取路徑對鎖的影響

依 SQL 性質分四類,使用不同鎖組合:

類型典型 SQL常用鎖模式
唯讀SELECT、FOR READ ONLYIS、S
傾向更改SELECT FOR UPDATEU、IX、X(表);S、U、X(行)
更改INSERT/UPDATE/DELETEIX、X
游標控制WHERE CURRENT OFIX、X

優化器選擇索引掃描傾向行鎖(IS);表掃描可能直接取表鎖(S)。良好的索引設計能減少鎖衝突。

總結:考試必備重點速記

  • 事務:COMMIT 永久化,ROLLBACK 復原,失敗自動回滾
  • 四大隔離級別:RR(最嚴、鎖全掃描)、RS(鎖已讀、允許幻像)、CS(預設、鎖當前行)、UR(最鬆、幾乎不鎖)
  • 11 種鎖模式:IN→IS→NS→S→IX→SIX→U→NW→X→WE→Z(由弱到強)
  • 鎖管理:隱式行鎖為主,可手動升級表鎖;注意升級、轉換、超時、死鎖機制
  • 效能權衡:嚴格隔離 ↔ 高並發,行鎖 ↔ 表鎖,需依業務場景調校

掌握這些核心機制,不僅能通過 730 認證,更能在實戰中設計出高並發、強一致的 DB2 應用系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved