| 模式代碼 | 名稱 | 簡稱 | 典型操作 | 兼容性 |
|---|---|---|---|---|
| 0 | None | - | 無鎖 | - |
| 1 | Null | NULL | SELECT (無 FOR UPDATE) | 與所有模式兼容 |
| 2 | Row Share | RS (SS) | SELECT FOR UPDATE, LOCK TABLE ... ROW SHARE | 兼容 1-5,阻塞 6 |
| 3 | Row Exclusive | RX (SX) | INSERT/UPDATE/DELETE, LOCK TABLE ... ROW EXCLUSIVE | 兼容 1-2,阻塞 3-6 |
| 4 | Share | S | CREATE INDEX, LOCK TABLE ... SHARE | 兼容 1,阻塞 2-6 |
| 5 | Share Row Exclusive | SRX (SSX) | FK 約束下的 UPDATE/DELETE, LOCK TABLE ... SHARE ROW EXCLUSIVE | 僅兼容 1,阻塞 2-6 |
| 6 | Exclusive | X | ALTER/DROP/TRUNCATE TABLE, LOCK TABLE ... EXCLUSIVE | 與所有其他模式互斥 |
| 操作 | 鎖模式 | 備註 |
|---|---|---|
| SELECT (普通) | 1 (Null) | 有時不顯示於 V$LOCKED_OBJECT |
| SELECT FOR UPDATE | 3 (RX) | 游標開啟期間鎖定返回行,阻塞其他 UPDATE/DELETE/SELECT FOR UPDATE |
| INSERT / UPDATE / DELETE | 3 (RX) | 同一行記錄順序串行化,後者等待前者 COMMIT/ROLLBACK |
| CREATE INDEX | 4 (S) | 阻塞 DML,不阻塞 SELECT |
| FK 父表 UPDATE/DELETE | 4/5 (S/SRX) | 檢查子表外鍵,鎖定子表對應行 |
| ALTER TABLE / DROP / TRUNCATE | 6 (X) | 獨佔全表,阻塞所有操作 |
COL OWNER FOR A12
COL OBJECT_NAME FOR A16
SELECT B.OWNER, B.OBJECT_NAME, L.SESSION_ID, L.LOCKED_MODE
FROM V$LOCKED_OBJECT L, DBA_OBJECTS B
WHERE B.OBJECT_ID = L.OBJECT_ID;
SELECT T2.USERNAME, T2.SID, T2.SERIAL#, T2.LOGON_TIME
FROM V$LOCKED_OBJECT T1, V$SESSION T2
WHERE T1.SESSION_ID = T2.SID
ORDER BY T2.LOGON_TIME;
SELECT
S.SID, S.SERIAL#, S.USERNAME, S.MACHINE, S.PROGRAM, S.LOGON_TIME,
L.LMODE, L.REQUEST, L.TYPE, L.ID1, L.ID2,
O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE,
DECODE(L.LMODE, 0,'NONE',1,'NULL',2,'RS',3,'RX',4,'S',5,'SRX',6,'X') HELD_MODE,
DECODE(L.REQUEST, 0,'NONE',1,'NULL',2,'RS',3,'RX',4,'S',5,'SRX',6,'X') REQUESTED_MODE
FROM V$LOCK L, V$SESSION S, DBA_OBJECTS O
WHERE L.SID = S.SID
AND L.ID1 = O.OBJECT_ID(+)
AND (L.LMODE > 0 OR L.REQUEST > 0)
ORDER BY S.LOGON_TIME;
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
IMMEDIATE (10g+) 使會話立即終止並回滾,不等待當前調用完成。
# 絕對禁止
kill -9
kill
原因:一個用戶進程可能持有多個鎖 (多個 V$LOCKED_OBJECT 記錄),OS Kill 只清除進程,**不會自動釋放鎖結構**,導致殘留鎖阻塞其他會話,甚至需重啟 Instance 才能清理。
-- 當前阻塞鏈
SELECT
BLOCKING_SESSION, BLOCKING_SESSION_STATUS,
SID, SERIAL#, USERNAME, EVENT, SECONDS_IN_WAIT,
SQL_ID, PREV_SQL_ID
FROM V$SESSION
WHERE BLOCKING_SESSION IS NOT NULL
ORDER BY SECONDS_IN_WAIT DESC;
-- 歷史鎖等待 (需診斷包授權)
SELECT * FROM DBA_HIST_ACTIVE_SESS_HISTORY
WHERE EVENT LIKE 'enq:%' AND SESSION_STATE = 'WAITING'
ORDER BY SAMPLE_TIME DESC;
SELECT ... FOR UPDATE NOWAIT 或 SKIP LOCKED (11g+) 避免無限等待