DML 鎖(Data Lock)保障多用戶並發操作時的資料完整性,防止衝突的 DML 與 DDL 同時發生。主要分為行鎖(Row Locks,TX)與表鎖(Table Locks,TM),不同 DML 操作會自動請求對應鎖。
當事務執行 INSERT、UPDATE、DELETE、MERGE 或 SELECT ... FOR UPDATE 時,對目標行加排他鎖(Exclusive Lock),直到 COMMIT 或 ROLLBACK 釋放。行鎖防止兩個事務同時修改同一行,提供最高並發度。
獲得行鎖的同時,事務也會在所屬表上加子排他鎖(Subexclusive, SX),阻止衝突的 DDL 操作(如 DROP TABLE、ALTER TABLE)。
建立測試表並初始化:
CREATE TABLE employees(employee_id NUMBER(10), salary NUMBER(10));
INSERT INTO employees VALUES(100, 512);
INSERT INTO employees VALUES(101, 600);
皆返回原始資料(100→512, 101→600),查詢不加鎖,互不干擾。
UPDATE employees SET salary = 612 WHERE employee_id = 100;
Session 1 獲得該行排他鎖。其他 Session 嘗試更新同一行將阻塞。
Session 2 獲得 101 行鎖。
展示 Oracle 讀取一貫性:各 Session 見到的資料版本取決於自身事務狀態。
鎖資訊儲存在 Data Block 中。資料庫使用佇列機制處理鎖請求:
執行 INSERT/UPDATE/DELETE/MERGE/SELECT FOR UPDATE/LOCK TABLE 時自動請求。阻止衝突的 DDL。
| 模式 | 縮寫 | 別名 | 特性 | 相容性 |
|---|---|---|---|---|
| Row Share | RS | Subshare (SS) | 鎖定表上特定行,意圖更新。限制最小,支援高並發行修改 | 與 RS、RX、S、SRX 相容;與 X 衝突 |
| Row Exclusive | RX | Subexclusive (SX) | 更新表行或 SELECT FOR UPDATE。允許其他事務查詢、插入、更新、刪除、鎖定多行 | 與 RS、RX 相容;與 S、SRX、X 衝突 |
| Share | S | — | 允許查詢(除 FOR UPDATE),僅持有者可更新。多事務可同時持有 S,但不保證能修改 | 與 RS、S 相容;與 RX、SRX、X 衝突 |
| Share Row Exclusive | SRX | Share-Subexclusive (SSX) | 比 S 更強。同一時間僅一事務可持有。允許查詢,禁止更新 | 僅與 RS 相容;與 RX、S、SRX、X 衝突 |
| Exclusive | X | — | 限制最強。禁止任何 DML 與任何鎖請求 | 與所有模式衝突 |
請求模式 → | RS | RX | S | SRX | X
持有模式 ↓ | | | | |
RS | Y | Y | Y | Y | N
RX | Y | Y | N | N | N
S | Y | N | Y | N | N
SRX | Y | N | N | N | N
X | N | N | N | N | N
Y=相容,N=衝突。實務上最常見為 RX(DML 隱式鎖)與 RS(SELECT FOR UPDATE 觸發)。
SELECT ... FOR UPDATE NOWAIT 或 SKIP LOCKED 避免無限等待V$SESSION、V$LOCK 排查鎖爭用