关于ORACLE的阻塞的问题

sunday_wu 2014-08-30 02:28:04
我负责的系统目前出现了这样一个情况,系统忙的时候,会出现数据库后台有大量ACTIVE会话,经过查看,大部分的会话都是调用后台的存储过程的,而且如果不重启应用,这些会话根本就不会释放,这个时候看服务器的性能又没有特别的异常。
我们分析过,这些存储过程在平常的时候执行都很快,DBA说因为数据库产生了锁,但是我觉得奇怪的时候,其中某一个存过的调用占了1/3的会话数,但这个存过并没有UPDATE或者INSERT任何数据,仅仅是一些简单的查询和函数操作,按道理来说不应该会阻塞或者被其它阻塞的,存过代码如下:
FUNCTION FUNC1(p_OrderType IN VARCHAR2, p_Org IN VARCHAR2)
RETURN VARCHAR2 IS
BEGIN
DECLARE
v_seqNo NUMBER(8);
v_orderNow DATE;
v_orgAbbr VARCHAR2(4);
BEGIN
-- 非法类型判断
IF (p_OrderType NOT IN ('IB', 'OB', 'DB', 'CB', 'EB', 'PC', 'DM', 'LC', 'CK','RK','EK', 'RO', 'RP', 'DN')) THEN
Raise_application_error(-20005, '无效的单据类型,无法生成单据编号!');
END IF;

-- 取得当前日期
v_orderNow := SYSDATE;
SELECT SEQ_ORDER.NEXTVAL INTO v_seqNo FROM dual;

BEGIN
-- 取得用户所在组织的缩写(PS:这张表的数据不大,执行这个SQL是很快的)
SELECT orgabbr
INTO v_orgAbbr
FROM misouprofile
WHERE orgid = p_Org;
EXCEPTION
WHEN OTHERS THEN
Raise_application_error(-20093, '找不到对应的组织缩写');
END;
-- 根据序列以及日期,类型,组织缩写生成流水号
RETURN p_OrderType || v_orgAbbr || to_char(v_orderNow, 'yyyyMMdd') || LPAD(v_seqNo,8,0);
END;
END;

我们做了一个实验,当数据库出现大量ACTIVE的会话的时候,我们在PL/SQL DEV上直接执行上面那个存过,会一直挂起;但是把里面的代码拷贝出来直接执行,就马上执行完了;难道是存过的那个包被锁住了,所以那个时候执行那个包里面的存过会阻塞?
请大侠指点。。。。。
...全文
455 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
bw555 2014-09-01
  • 打赏
  • 举报
回复
引用 4 楼 sunday_wu 的回复:
[quote=引用 3 楼 bw555 的回复:] 重点检查此下两个方面 1、需要重点检查阻塞时其他sql语句是否有与此过程相关的语句 2、调用此过程的位置是否存在死循环或是递归操作 有可能是调用速度比执行速度快,造成总是有大量此过程等待执行
但是那个时候在PL/SQL DEV里面执行那个存过都阻塞,而把里面的SQL提出来执行就很快执行完了,这个如何解释?[/quote] 你的存储过程调用了序列SEQ_ORDER,监控一下这个序列增长的速度,先确认是不是调用频率过高造成的 假设你服务器每秒最快能处理这个过程1000次,如果死循环每秒调用了1200次,这时候你查询会总是有没执行完的这个过程
sunday_wu 2014-08-31
  • 打赏
  • 举报
回复
引用 1 楼 bw555 的回复:
先查一查数据库正在执行的sql语句,可能会有新的发现
SELECT b.sid oracleID,  
       b.username 登录Oracle用户名,  
       b.serial#,  
       spid 操作系统ID,  
       paddr,  
       sql_text 正在执行的SQL,  
       b.machine 计算机名  
FROM v$process a, v$session b, v$sqlarea c  
WHERE a.addr = b.paddr  
   AND b.sql_hash_value = c.hash_value
查询Oracle正在执行的sql语句
帖子已经说了,我就是通过看正在执行的会话和SQL,看到有很多活动的会话正在执行那个存过
sunday_wu 2014-08-31
  • 打赏
  • 举报
回复
引用 3 楼 bw555 的回复:
重点检查此下两个方面 1、需要重点检查阻塞时其他sql语句是否有与此过程相关的语句 2、调用此过程的位置是否存在死循环或是递归操作 有可能是调用速度比执行速度快,造成总是有大量此过程等待执行
但是那个时候在PL/SQL DEV里面执行那个存过都阻塞,而把里面的SQL提出来执行就很快执行完了,这个如何解释?
bw555 2014-08-31
  • 打赏
  • 举报
回复
重点检查此下两个方面 1、需要重点检查阻塞时其他sql语句是否有与此过程相关的语句 2、调用此过程的位置是否存在死循环或是递归操作 有可能是调用速度比执行速度快,造成总是有大量此过程等待执行
bw555 2014-08-30
  • 打赏
  • 举报
回复
先查一查数据库正在执行的sql语句,可能会有新的发现
SELECT b.sid oracleID,  
       b.username 登录Oracle用户名,  
       b.serial#,  
       spid 操作系统ID,  
       paddr,  
       sql_text 正在执行的SQL,  
       b.machine 计算机名  
FROM v$process a, v$session b, v$sqlarea c  
WHERE a.addr = b.paddr  
   AND b.sql_hash_value = c.hash_value
查询Oracle正在执行的sql语句

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧