| 類別 | 保護對象 | 代表鎖 |
| DML 鎖 (Data Locks) | 資料完整性 | TM 鎖(表級)、TX 鎖(交易/行級) |
| DDL 鎖 (Dictionary Locks) | 物件結構定義 | 排他 DDL 鎖、共享 DDL 鎖、可中斷剖析鎖 |
| 內部鎖與 Latch | 記憶體結構、緩衝區 | Latch、Mutex、Buffer Pin 等 |
本文聚焦 DML 鎖,因其直接影響應用並發效能。
DML 雙層鎖架構:TM → TX
- 執行 DML 時,系統先在目標表申請 TM 鎖(表級)
- 獲得 TM 鎖後,再申請 TX 鎖(行級) 並置位具體資料列鎖標誌
- 優勢:檢查 TM 鎖模式相容性即可,避免逐列掃描 TX 鎖,大幅提升效率
TM 鎖模式對照表(0-6)
| 模式 | 代碼 | 名稱 | 描述 | 觸發 SQL |
| None | 0 | - | 無鎖 | - |
| NULL | 1 | - | 空鎖 | SELECT |
| SS (Row-S) | 2 | Row Share | 行級共享,其他僅能查詢 | SELECT FOR UPDATE, LOCK TABLE ... ROW SHARE |
| SX (Row-X) | 3 | Row Exclusive | 行級排他,提交前禁止 DML | INSERT/UPDATE/DELETE, LOCK TABLE ... ROW EXCLUSIVE |
| S (Share) | 4 | Share | 共享鎖 | CREATE INDEX, LOCK TABLE ... SHARE |
| SSX (S/Row-X) | 5 | Share Row Exclusive | 共享行級排他 | LOCK TABLE ... SHARE ROW EXCLUSIVE |
| X (Exclusive) | 6 | Exclusive | 排他鎖 | ALTER/DROP/TRUNCATE TABLE, LOCK TABLE ... EXCLUSIVE |
TX 鎖特性
- 資料列上僅存在 X 鎖(排他鎖)
- 事務首發 DML 時獲得,持有至 COMMIT/ROLLBACK
- 多 Session 同列 DML → 首鎖者持有,其餘等待(
ENQ: TX - ROW LOCK CONTENTION)
鎖等待監控與解決
關鍵動態視圖
| 視圖 | 用途 |
| V$LOCK | 當前鎖持有與等待,識別 TYPE=TM/TX |
| V$SESSION | Session 資訊,關聯 SID、BLOCKING_SESSION |
| V$SESSION_WAIT | 等待事件細節 |
| DBA_BLOCKERS / DBA_WAITERS | 阻塞者/等待者快速查詢 |
快速定位阻塞鏈 SQL
-- 找出阻塞者
SELECT s.sid, s.serial#, s.username, s.machine, s.sql_id, l.type, l.lmode, l.request
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND l.block = 1
AND l.type IN ('TM','TX');
-- 完整阻塞鏈
SELECT blocking_session, sid, seconds_in_wait, event
FROM v$session
WHERE blocking_session IS NOT NULL;
處理步驟
- 識別持鎖 Session(
BLOCKING_SESSION)
- 聯繫應用負責人確認業務邏輯,決定 COMMIT 或 ROLLBACK
- 緊急情況:
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
- 事後分析:索引缺失、長交易、應用邏輯缺陷
死鎖診斷與解決
特徵
- Oracle 自動偵測,犧牲一條語句回滾,回報 ORA-00060
- 警示日誌
ALERT_.log 記錄錯誤
USER_DUMP_DEST 產生追蹤檔(ora__.trc),含完整死鎖圖
追蹤檔關鍵資訊
*** 2024-01-15 10:30:45.123
DEADLOCK DETECTED ( ORA-00060 )
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-0001000a-00000012 12 145 X 18 167 S
TX-0001000b-00000015 18 167 X 12 145 S
Session 145: DID 0001-000C-00000001
Session 167: DID 0001-0012-00000002
Rows waited on:
Session 145: obj - rowid = 00012345 - AAAABCAAEAAAABTAAA
(dictionary objn - 74565, file - 4, block - 123, slot - 0)
Session 167: obj - rowid = 00012346 - AAAABCAAEAAAABTAAB
(dictionary objn - 74566, file - 4, block - 124, slot - 0)
常見死鎖模式與對策
| 模式 | 特徵 | 解決方案 |
| 行級交叉更新 | Session A 鎖表 1 改表 2,Session B 鎖表 2 改表 1 | 統一表存取順序(如按表名字母序) |
| 無索引外鍵 | 子表無索引導致父表 DML 鎖全表掃描 | 為外鍵欄位建立索引 |
| Bitmap 索引 | 並發 DML 觸發 Bitmap 區塊鎖升級 | 改為 B-Tree 索引(如案例中 IND_T_PRODUCT_HIS_STATE) |
| ITL 槽不足 | 區塊內 ITL 耗盡導致等待 | 增加 INITRANS 或 MAXTRANS |
實戰檢查清單
- [ ] 所有外鍵欄位是否有索引?
- [ ] 高並發表是否避免使用 Bitmap 索引?
- [ ] 應用是否統一多表操作順序?
- [ ] 是否監控
V$LOCK 告警?
- [ ] 追蹤檔目錄
USER_DUMP_DEST 是否有空間?
結語
鎖等待是症狀,死鎖是病變。預防勝於治療:設計階段建索引、定存取順序、選對索引類型;運行期建立鎖監控儀表板,追蹤檔自動告警。遇 ORA-00060 先看追蹤檔圖,再對表治療。
- 上一篇文章: Oracle 連接查詢完全指南:LEFT JOIN、RIGHT JOIN、FULL JOIN 與舊式外連接語法對照
- 下一篇文章: Oracle 資料字典全景指南:靜態視圖三大前綴與動態效能視圖實戰查詢
Copyright ©
程式碼之家 All Rights Reserved