U kunt DBMS_LOCK.request
om een unieke slotgreep te genereren. Slechts één sessie kan deze vergrendeling tegelijkertijd vasthouden. Als de database opnieuw wordt opgestart of de sessie onverwacht eindigt, wordt de vergrendeling automatisch opgeheven.
U beslist bij het aanvragen van de vergrendeling of de vergrendeling wordt vastgehouden voor alle commits of niet.
Hier is een voorbeeld:
SQL> CREATE OR REPLACE PROCEDURE serial IS
2 l_lock_handle VARCHAR2(128 BYTE);
3 l_lock_request INTEGER;
4 BEGIN
5 dbms_lock.allocate_unique(lockname => 'MY_SERIAL_PROC',
6 lockhandle => l_lock_handle);
7 l_lock_request := dbms_lock.request(lockhandle => l_lock_handle,
8 timeout => 5,
9 release_on_commit => FALSE);
10 CASE l_lock_request
11 WHEN 0 THEN
12 NULL; -- success
13 WHEN 1 THEN
14 raise_application_error(-20002, 'lock already reserved');
15 ELSE
16 raise_application_error(-20001, 'Lock error: ' || l_lock_request);
17 END CASE;
18 BEGIN
19 ---------- serialized block of code ----------
20 ---------- (lock will be kept accross commit) ----------
21 dbms_lock.sleep(30);
22 ---------- End of serialized code ----------
23 EXCEPTION
24 WHEN OTHERS THEN -- release lock in case of uncatched error
25 l_lock_request := dbms_lock.release(lockhandle => l_lock_handle);
26 RAISE;
27 END;
28 l_lock_request := dbms_lock.release(lockhandle => l_lock_handle);
29 END;
30 /
Procedure created
Ik geef twee sessies tegelijk:
Session A> exec serial;
Session B> -- Before session A ends
Session B> exec serial;
ERROR at line 1:
ORA-20002: lock already reserved
ORA-06512: at "APPS.SERIAL", line 13
ORA-06512: at line 1
PL/SQL procedure successfully completed
Session B> -- After session A ends
Session B> exec serial;
PL/SQL procedure successfully completed.