Erp100论坛's Archiver

xiangzhao 发表于 2008-7-9 14:18

如何判断一个存储过程是否在执行

我们的应用中有两个地方都要调用一个相同的存储过程,这造成了一些冲突,因此我想有没有办法判断存储过程是否已经在执行,如果在执行后一个就退出,本来考虑用置标志位,但是容易造成设定后,一旦执行到一半出问题,标志位没改回去,以后都没有办法执行存储过程的问题。

xiangzhao 发表于 2008-7-9 14:18

create or replace procedure plsqlconcurrencysample
as
/* cnoug copyright*/
/* written by chao_ping to provide some sample for plsql concurrency control*/
v_lockhandle varchar2(4000);
v_result        number;
begin
dbms_lock.allocate_unique('PLSQL1',v_lockhandle);
v_result:=dbms_lock.REQUEST(LOCKHANDLE=>v_lockhandle,timeout=>0);
if
        v_result=0 then
        dbms_output.put_line('now begin to process ...at'||to_char(sysdate,'YYYYMMDD hh24:mi:ss'));
        dbms_lock.sleep(60);
        dbms_output.put_line('finished work at'||to_char(sysdate,'YYYYMMDD HH24:mi:ss'));
        v_result:=dbms_lock.release(lockhandle=>v_lockhandle);
else
        dbms_output.put_line('someone else working...');
end if;

exception
        when others then
        dbms_output.put_line('ERROR'||sqlerrm);
        v_result:=dbms_lock.release(lockhandle=>v_lockhandle);
end;

xiangzhao 发表于 2008-7-9 14:19

使用这个过程就可以看到谁在执行一个存储过程
create or replace procedure sys.who_is_using(obj_name varchar2) is
begin
dbms_output.enable(1000000);
   for i in (SELECT distinct b.username,b.sid
             FROM SYS.x$kglpn a,v$session b,SYS.x$kglob c
             WHERE a.KGLPNUSE = b.saddr
               and upper(c.KGLNAOBJ)  like upper(OBJ_NAME)
               and a.KGLPNHDL = c.KGLHDADR)
               loop
   dbms_output.put_line('('||to_char(i.sid)||') - '||i.username);
   end loop;
end;

xiangzhao 发表于 2008-7-9 14:19

如果该存储过程有读写数据的话,你可以用strace -p 进程号
看是不是有很多数据在读写,solaris用truss

查找进程号和SQL语句可以用
select a.program,
       a.machine,
       b.spid,  --进程号
       c.sql_text,
       a.status
  from v$session a,
       v$process b,
       v$sqlarea c
where a.paddr=b.addr
   and a.sql_hash_value=c.hash_value
   and a.sql_address=c.address
   and a.sid = ???;
--正在运行的语句

select a.program,
       a.machine,
       a.sid,
       c.sql_text,
       to_char(a.LOGON_TIME,'yyyy-mm-dd hh24:mi:ss')
  from v$session a,
       v$process b,
       v$sqlarea c
where a.paddr=b.addr
   and a.PREV_HASH_VALUE=c.hash_value
   and a.PREV_SQL_ADDR=c.address
   and a.sid = ???;
--已经运行完的语句


你也可以用
select TIME_REMAINING,ELAPSED_SECONDS from v$session_longops  where sid =???
看看TIME_REMAINING是什么值

xiangzhao 发表于 2008-7-9 14:19

select count(*)  into vn_number
       from SYS.V_$ACCESS a,SYS.V_$session b where a.type='PROCEDURE'
           and a.OBJECT like 存储过程名称'  and a.sid=b.sid and b.status='ACTIVE';--判断当前存储过程是否正在运行!

页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2007 Comsenz Inc.