0

一度に 1 つずつ実行するプロシージャがあります。つまり、プロシージャが他のプロセス/ユーザーを実行しているとき、同じプロシージャを実行できないはずです。

プロシージャが実行された後、次に実行できるようになったときのみ

助けてください

4

1 に答える 1

2

プロシージャの実行をシリアル化するには、dbms_lockパッケージ、具体的allocate_unique()にはそのパッケージのrelease()プロシージャとrequest()関数を使用できます。以下は、ロック取得プロセスを規制するパッケージを作成する例です。

パッケージの仕様

create or replace package proc_lock as
  function request_lock( p_lock_name   in varchar2) return varchar2;
  procedure release_lock(p_l_handle in varchar2);
end;

パッケージ本体

create or replace package body proc_lock as
  function request_lock( p_lock_name   in varchar2) return varchar2
  is
    l_request     number;
    l_lock_handle varchar2(1000);
  begin
    dbms_lock.allocate_unique(p_lock_name, l_lock_handle);
    -- waits 5 sec trying to acquire a lock
    l_request := dbms_lock.request(l_lock_handle, timeout=>5);
    if l_request <> 0
    then
      raise_application_error(-20001, 'Lock cannot be acquired.');
    end if;
    return l_lock_handle;
  end;

  procedure release_lock(p_l_handle in varchar2)
  is
  begin
    if dbms_lock.release(p_l_handle) > 0
    then
      raise_application_error(-20000, 'Cannot release lock');
    end if;
  end;
end;

シリアル化する必要がある簡単な手順を次に示します。

create or replace procedure test_proc
is
  l_handle       varchar2(1000);   -- lock handle
begin
  -- trying to acquire a lock
  l_handle := proc_lock.request_lock('test');
  -- here goes all usefull work that this procedure 
  -- would do if lock acquired successfully 
  dbms_output.put_line('procedure is working');
  -- mimic large amount of work
  dbms_lock.sleep(10);
  dbms_output.put_line('procedure is done');
  -- release the lock after work is done
  proc_lock.release_lock(l_handle);
end;

テストケース:

--Session #1
SQL> exec test_proc;

--Session #2 at the same time
SQL> exec test_proc;

BEGIN test_proc; END;

*
ERROR at line 1:
ORA-20001: Lock cannot be acquired. 
ORA-06512: at "HR.PROC_LOCK", line 11 
ORA-06512: at "HR.TEST_PROC", line 6 
ORA-06512: at line 1 

--Session #1
SQL> exec test_proc;
procedure is working                                                            
procedure is done                                                               

PL/SQL procedure successfully completed.

詳しくdbms_lockパッケージをご覧ください。

于 2013-09-20T18:02:02.797 に答える