-- 1. 查哪些表被鎖
SELECT b.owner, b.object_name, a.session_id, a.locked_mode
FROM v$locked_object a, dba_objects b
WHERE b.object_id = a.object_id;
-- 2. 查對應 Session 詳細資訊
SELECT b.username, b.sid, b.serial#, b.logon_time
FROM v$locked_object a, v$session b
WHERE a.session_id = b.sid
ORDER BY b.logon_time;
-- 3. 殺掉 Session
ALTER SYSTEM KILL SESSION 'sid,serial#';
-- 若報 ORA-00031,加 IMMEDIATE
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- 1. 查被鎖的程序 (V$DB_OBJECT_CACHE)
SELECT * FROM V$DB_OBJECT_CACHE
WHERE OWNER = '<schema>' AND LOCKS != '0';
-- 2. 查存取該程序的 SID (V$ACCESS)
SELECT * FROM V$ACCESS
WHERE OWNER = '<schema>' AND NAME = '<procedure_name>';
-- 3. 取得 SID、SERIAL#、PADDR (V$SESSION)
SELECT SID, SERIAL#, PADDR FROM V$SESSION WHERE SID = '<sid>';
-- 4. 取得 OS Process ID (V$PROCESS)
SELECT SPID FROM V$PROCESS WHERE ADDR = '<paddr>';
-- 5. 先殺 Oracle Session,再殺 OS 進程
ALTER SYSTEM KILL SESSION 'sid,serial#';
-- Unix: kill -9 <spid> Windows: orakill <sid> <spid>
SELECT t2.username || ' ' || t2.sid || ' ' || t2.serial# || ' ' || t2.logon_time || ' ' || t3.sql_text
FROM v$locked_object t1, v$session t2, v$sqltext t3
WHERE t1.session_id = t2.sid
AND t2.sql_address = t3.address
ORDER BY t2.logon_time;
-- 拿到 sid, serial# 後
ALTER SYSTEM KILL SESSION 'sid,serial#';
SELECT a.username, c.spid AS os_pid, c.pid AS oracle_pid
FROM v$session a, v$process c
WHERE c.addr = a.paddr
AND a.sid = <sid>
AND a.serial# = <serial#>;
-- Unix
ps -ef | grep <os_pid>
kill -9 <os_pid>
ps -ef | grep <os_pid> # 確認已終止
v$locked_object + v$session 定位 Session,KILL SESSION IMMEDIATE 通常足夠;kill -9;FOR UPDATE NOWAIT,需結合 Trace 文件 (udump) 定位具體 SQL (錯誤碼 ORA-00054);死鎖處理核心:快速定位 → 優雅殺 Session → 必要時清理 OS 進程 → 事後根因分析 (索引缺失、邏輯缺陷、並發設計)。掌握四種查詢視角,應對各類鎖定場景遊刃有餘。