Oracle用户是否可以获得自己的运行会话列表而无需访问v $ session?

Nic*_*int 2 oracle

我有一个运行进程的应用程序,我只希望一次运行一个进程.一些选项是:

  1. 使用对象锁定可防止后续进程运行.

    这没关系,但我希望调用会话立即返回,而不是等待正在运行的会话完成.

  2. 使用自定义Y/N设置进程是否正在运行.

    我在进程开始时设置了一个"Y"标志,并在完成或失败时将其设置为"N".也很好,但感觉我正在重新发明轮子,感觉不像是要走的路.如果运行会话被杀死,因为标志保持在"Y",它也会失败.

  3. 使用 dbms_application_info.set_module

    这种方法看起来最强大,但如果我知道现有的运行进程,我认为我需要能够查询v$session,我不希望这个应用程序具有如此广泛的访问权限.

有任何想法吗?

Rob*_*ijk 6

选项4:使用DBMS_LOCK序列化访问.以下是文档的链接:http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10577/d_lock.htm#i1002556

一个例子:

首先创建一个辅助过程来序列化对某个过程的访问.该过程使用过程的名称来生成唯一的锁定句柄.'NOTORA $'确保锁名不以'ORA $'开头,因为它们是为Oracle保留的.

SQL> create procedure serialize_access (p_procedure_name in varchar2)
  2  is
  3    l_lockhandle varchar2(128);
  4    l_return     integer;
  5  begin
  6    dbms_lock.allocate_unique
  7    ( lockname   => 'NOTORA$' || p_procedure_name
  8    , lockhandle => l_lockhandle
  9    );
 10    l_return := dbms_lock.request
 11    ( lockhandle        => l_lockhandle
 12    , lockmode          => dbms_lock.x_mode
 13    , timeout           => 0  -- do not wait
 14    , release_on_commit => true
 15    );
 16    if l_return = 1
 17    then
 18      raise_application_error
 19      ( -20000
 20      , 'Someone else is running this procedure, so you''ll have to wait'
 21      );
 22    end if;
 23  end serialize_access;
 24  /

Procedure created.
Run Code Online (Sandbox Code Playgroud)

在您的过程中调用此serialize_access过程,如下所示:

SQL> create procedure p1
  2  is
  3  begin
  4    serialize_access('p1');
  5    dbms_lock.sleep(30);
  6  end;
  7  /

Procedure created.
Run Code Online (Sandbox Code Playgroud)

其中dbms_lock.sleep用作实际代码的替代品.现在打开两个或更多其他会话并发出"exec p1"命令.第一节将以等待30秒开始.第二场会议将向您展示:

ERROR at line 1:
ORA-20000: Someone else is running this procedure, so you'll have to wait
ORA-06512: at "[schema].SERIALIZE_ACCESS", line 18
ORA-06512: at "[schema].P1", line 4
ORA-06512: at line 1
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

问候,Rob.