許多開發者以為 Parallel DML 僅鎖定修改的行,實測發現:Parallel UPDATE 會對整張表加排他鎖 (TM-X),導致同表其他 Session 的 DML 完全阻塞。本文以實驗證實此行為,並解析 V$LOCK 關鍵欄位含義。
-- Session 1:並行更新
ALTER SESSION FORCE PARALLEL DML;
UPDATE /*+ PARALLEL(t,4) */ test t SET object_name='ggg' WHERE object_type='TABLE';
-- 持有鎖,未提交
-- Session 2:嘗試更新不同條件行
UPDATE test t SET object_name='ggg' WHERE object_type='INDEX';
-- Hang 住,等待 TM 鎖
-- Session 3:查詢鎖狀態
SELECT sid, type, id1, id2, lmode, request, ctime, block
FROM v$lock WHERE sid IN (8,11) ORDER BY sid;
| SID | TYPE | ID1 | ID2 | LMODE | REQUEST | BLOCK | 說明 |
|---|---|---|---|---|---|---|---|
| 11 (Session 1) | TM | 80189 (OBJECT_ID) | 0 | 6 (X) | 0 | 1 | 持有表排他鎖,阻塞他人 |
| 11 | TX | 196620 | 5212 | 6 (X) | 0 | 0 | 事務排他鎖 |
| 8 (Session 2) | TM | 80189 | 0 | 0 | 3 (SX) | 0 | 請求 Row-X (SX) 兼容鎖,被 X 鎖阻塞 |
| 8 | AE | 100 | 0 | 4 | 0 | 0 | 版本鎖 |
結論:Session 1 並行更新持有 TM 模式 6 (Exclusive),Session 2 請求模式 3 (Row-X/SX) 即被阻塞。V$LOCKED_OBJECT 同樣顯示 OBJECT_ID=80189 的 LOCKED_MODE=6 (X) 與 0 (None)。
| 欄位 | 含義 |
|---|---|
| TYPE | TM=DML Enqueue, TX=Transaction Enqueue, UL=User Lock, 其他為系統鎖 |
| ID1 (TM) | 被鎖表的 OBJECT_ID |
| ID1 (TX) | 十進制編碼:0xRRRRSSSS (RRRR=Undo Segment, SSSS=Slot) |
| ID2 (TX) | Wrap 計數(Slot 重用次數) |
| LMODE / REQUEST | 0=None, 1=Null, 2=Row-S (SS), 3=Row-X (SX), 4=Share (S), 5=S/Row-X (SSX), 6=Exclusive (X) |
| BLOCK | 1=正在阻塞其他 Session, 0=未阻塞 |
CREATE TABLE new AS SELECT ... + 重建索引/約束 + 重命名,鎖定時間極短。V$LOCK 發現 TM-X 長持有者並告警。