oracle的存储过程被锁,杀掉对应的进程

🔍 核心原因:DDL锁冲突

当你要编译(ALTER)一个存储过程时,Oracle需要给它加上一个排他DDL锁(Exclusive DDL Lock) -2-9。如果这时有其他会话正在执行修改 同一个存储过程,或者是这个存储过程正在被调试 ,Oracle就会因为无法获得这个排他锁而导致编译操作被挂起或超时-2-10

🛠️ 解决步骤:定位并杀掉阻塞会话

以下是标准的排查与解决流程:

第一步:查找锁住的对象

首先,查询V$DB_OBJECT_CACHE视图,确认你的存储过程是否确实被锁,以及锁的数量-2-3-4。把YOUR_PROC_NAME换成你的存储过程名(注意用大写)。

sql

复制

下载

复制代码
SELECT * FROM V$DB_OBJECT_CACHE 
WHERE name = 'YOUR_PROC_NAME' AND LOCKS != '0';

如果查询有结果且LOCKS大于0,就说明确实被锁了。

第二步:找出阻塞会话的SID

通过V$ACCESS视图,找出是哪个会话(SID)锁住了这个对象-2-3-4

sql

复制

下载

复制代码
SELECT /*+ rule */ SID FROM V$ACCESS 
WHERE object = 'YOUR_PROC_NAME';

记下这里查出来的SID

第三步:获取会话的SERIAL#

根据上一步得到的SID,查询V$SESSION视图获取对应的SERIAL#,杀掉会话时这两个信息都需要-2-3-4

sql

复制

下载

复制代码
SELECT SID, SERIAL#, PADDR FROM V$SESSION 
WHERE SID = '刚才查到的SID';

第四步:杀掉阻塞会话

拥有SIDSERIAL#后,就可以执行命令强制结束这个会话,释放它占用的锁-2-3-4

sql

复制

下载

复制代码
ALTER SYSTEM KILL SESSION 'sid值, serial#值' IMMEDIATE;

成功执行这个命令后,再尝试编译你的存储过程,应该就可以了

SELECT * FROM V$DB_OBJECT_CACHE

WHERE name = 'ZZTEST' AND LOCKS != '0';

SELECT /*+ rule */ SID FROM V$ACCESS

WHERE object = 'ZZTEST';

SELECT SID, SERIAL#, PADDR FROM V$SESSION

WHERE SID = '2269';

ALTER SYSTEM KILL SESSION '2269, 15933' IMMEDIATE;