2013-09-20 3 views
0

У меня есть процедура, которая должна выполняться по одному. Я имею в виду, что при выполнении процедуры другой процесс/пользователь не должен выполнять одну и ту же процедуру.Процедура Oracle 10g, выполняющая параллель

только после того, как процедура выполняется и тому, в следующий раз он может быть выполнен

Пожалуйста, помогите

+0

Можете ли вы поделиться процедурой? – ChrisProsser

+0

Его общая процедура. Единственное, что НЕ должно быть разрешено выполнять параллельно. – user2788258

ответ

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. 

Find out more о dbms_lock упаковка.

+0

спасибо много помощнику. Позвольте мне попробовать. – user2788258