用lockhandle的方法获得锁,因为锁的名称是比较容易辨别的,也是比较容易描述的。第一种方法不被oracle推荐。
在共享服务器模式和分布式事务时我们最好把release_on_commit设置为true。
FUNCTION DBMS_LOCK.RELEASE
(id IN INTEGER)
RETURN INTEGER;
FUNCTION DBMS_LOCK.RELEASE
(lockhandle IN VARCHAR2)
RETURN INTEGER;
参数 |
描述 |
id |
锁的数字标识 |
lockhandle |
ALLOCATE_UNIQUE返回的锁的handle |
返回值 |
描述 |
0 |
成功 |
3 |
参数错误 |
4 |
并没有拥有特定的锁 |
5 |
不合法的lockhandle |
RELEASE 函数用来释放先前申请的锁。当锁不用时最好立即释放,这是很好的习惯。锁本身就是宝贵的资源,并且可以尽早释放被锁住的资源,而且可以有效地避免死锁。
如何使用这些api,很容易只要在我们的存储过程之前或者之后调用申请锁,释放锁(或者在事务提交或rollback的时候自动释放锁)就可以了,但这样也带来了存储过程代码的侵入性,每个存储过程都必须调用申请锁,释放锁。我们可以写一个wrapper把锁的申请和释放包裹起来。类似于模板模式。
create or replace package FRM_TEST_TESTING is
PROCEDURE loop4_specific_round;
end FRM_TEST_TESTING;
create or replace package body FRM_TEST_TESTING is
-- Function and procedure implementations
--PROCEDURE loop4_specific_round(p_loop_count IN INTEGER) AS
PROCEDURE loop4_specific_round AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR r IN 1 .. 60 LOOP
SYS.dbms_lock.sleep(20);
DBMS_OUTPUT.PUT_LINE(''During testing SP executing. ''|| to_char(sysdate,''MM/DD/YYYY HH24:MI:SS''));
insert into TEST_TEST
(name, Creationtime)
values
(''1111'', sysdate);
commit;
END LOOP;
END loop4_specific_round;
end FRM_TEST_TESTING;
create or replace package frm_test_task_pkg is
function frm_test_task_func(i_lock_name in varchar2, i_procname in varchar2, i_expiration_time Integer default 864000, i_wait_time Integer default DBMS_LOCK.maxwait) return number;
end frm_test_task_pkg;
create or replace package body frm_test_task_pkg is
procedure app_task_wrapper_proc(i_procname in varchar2) as
PRAGMA AUTONOMOUS_TRANSACTION;
cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;
fdbk BINARY_INTEGER;
begin
DBMS_SQL.PARSE (cur,
''begin '' || i_procname || '';end;'',
DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.execute (cur);
DBMS_OUTPUT.put_line(''Fetch rows : '' || fdbk);
DBMS_SQL.close_cursor(cur);
commit;
end app_task_wrapper_proc;
function frm_test_task_func(i_lock_name in varchar2, i_procname in varchar2, i_expiration_time Integer default 864000, i_wait_time Integer default DBMS_LOCK.maxwait) return number is
v_result number;
v_lockhandle varchar2(200);
v_sid pls_integer;
begin
dbms_lock.allocate_unique(i_lock_name,
|