一般数据库中存储过程无法编辑,包无法编辑,导致的原因都是因为表的死锁,解决方法
1.一般情况只部署在一台机器的数据库可以单独杀死实例视图里所锁死的表即可.
--查看该实例锁死对象
SELECT s.username,
decode(l.type, 'TM', 'TABLE LOCK', 'TX', 'ROW LOCK', NULL) LOCK_LEVEL,
o.owner,
o.object_name,
o.object_type,
s.sid,
s.serial#
FROM v$session s, v$lock l, dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT NULL
AND O.OWNER='GDEGIS'--用户名
2.考虑到可能有些服务器上用的不只是一台机,可能用的是rac部署的多台机器。
所以首先将数据库所有的死锁表查询出来,查询数据库中的全局视图
--查看全局锁死对象
SELECT s.username,
decode(l.type, 'TM', 'TABLE LOCK', 'TX', 'ROW LOCK', NULL) LOCK_LEVEL,
o.owner,
o.object_name,
o.object_type,
s.sid,
s.serial#
FROM gv$session s, gv$lock l, dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT NULL
AND O.OWNER='GDEGIS'--用户名
可能你会发现有时候会报“会话ID不存在”的错误.
对比实例中和全局锁死的表数量
实例视图里没有的而全局有的死锁表,说明不存在当前实例节点,可以通过手动配置TNS登录到另外节点杀死锁死的会话
alter system kill session 'sid,serial;
一般通过这些就可以完全解决数据库表死锁问题,再不行只能登录到OS级杀死进程!
3.关于存储过程或者包无法编辑的问题一般都是由于表死锁造成的。比如数据库中的一个JOB一直在执行一个任务操作此表,
1.查看正在运行的job:
select * from dba_jobs_running;
2.查询job对应的s.sid,s.serial#:
select s.sid,s.serial# from v$session s where s.sid in (select sid from dba_jobs_running);
3.停止任务会话:
alter system kill session 'sid,serial;
4.断开JOB。
5.最后删除在执行的JOB。
注意:任务会话结束后,任务不一定就停止运行了,必须删除JOB。再通过查询死锁表语句查看是否有锁表,
假如没有,此时应该可以对存储过程或者包重新编辑了,或者在调用脚本杀除锁表会话。