oracle - 我可以使用 Oracle PL/SQL 同时持有两个锁吗?

标签 oracle plsql locking

我的应用程序的当前锁定概念假定持有 2 个锁并执行代码。但是当我尝试释放第一个锁柄时,我总是会出错。有没有办法做到这一点,还是我使用 dbms_lock 一次获得 2 个锁是错误的?

最好的问候!

DECLARE
  l_handle_1 VARCHAR2(128);
  l_handle_2 VARCHAR2(128);
  l_result NUMBER;
BEGIN

    -- >>> LOCK1
    dbms_lock.allocate_unique('lock_1', l_handle_1);
    l_result := dbms_lock.request(l_handle_1, dbms_lock.x_mode, 10, true);
    BEGIN

      -- >>> LOCK2
      dbms_lock.allocate_unique('lock_2', l_handle_2);
      l_result := dbms_lock.request(l_handle_2, dbms_lock.x_mode, 10, true);
      BEGIN

        /*
         * PLSQL-Code with both locks held
         */

        -- LOCK-2 release
        l_result := dbms_lock.release(l_handle_2);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 2');
        END IF;

        -- LOCK-1 release
        l_result := dbms_lock.release(l_handle_1);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 1');
        END IF;

      EXCEPTION
        WHEN OTHERS THEN
          l_result := dbms_lock.release(l_handle_2);
          IF (l_result > 0) THEN
            dbms_output.put_line('Fail 3');
          END IF;
          RAISE;          
      END;

    EXCEPTION
      WHEN OTHERS THEN
        l_result := dbms_lock.release(l_handle_1);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 4');
        END IF;
        RAISE;
    END;
END;

最佳答案

您调用 dbms_lock.request 并为第一个锁句柄设置 release_on_commit = TRUE,然后调用 allocate_unique。 allocate_unique 执行提交并因此释放第一个锁。

如果您按如下方式更改代码,您将不会收到错误:

DECLARE
  l_handle_1 VARCHAR2(128);
  l_handle_2 VARCHAR2(128);
  l_result NUMBER;
BEGIN


    dbms_lock.allocate_unique('lock_1', l_handle_1);
    dbms_lock.allocate_unique('lock_2', l_handle_2);

    -- >>> LOCK1
    l_result := dbms_lock.request(l_handle_1, dbms_lock.x_mode, 10, true);
    BEGIN

      -- >>> LOCK2
      -- dbms_lock.allocate_unique('lock_2', l_handle_2);
      l_result := dbms_lock.request(l_handle_2, dbms_lock.x_mode, 10, true);
      BEGIN

        /*
         * PLSQL-Code with both locks held
         */

        -- LOCK-2 release
        l_result := dbms_lock.release(l_handle_2);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 2');
        END IF;

        -- LOCK-1 release
        l_result := dbms_lock.release(l_handle_1);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 1');
        END IF;

      EXCEPTION
        WHEN OTHERS THEN
          l_result := dbms_lock.release(l_handle_2);
          IF (l_result > 0) THEN
            dbms_output.put_line('Fail 3');
          END IF;
          RAISE;          
      END;

    EXCEPTION
      WHEN OTHERS THEN
        l_result := dbms_lock.release(l_handle_1);
        IF (l_result > 0) THEN
          dbms_output.put_line('Fail 4');
        END IF;
        RAISE;
    END;
END;

关于oracle - 我可以使用 Oracle PL/SQL 同时持有两个锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11688127/

相关文章:

sql - 在 Oracle 中使用单个语句在表之间移动行

c# - ODP.NET Oracle.ManagedDataAcess 随机 ORA-12570 错误

SQL Server - 如何锁定表直到存储过程完成

objective-c - 这个递归同步调用怎么不死锁呢?

plsql - 为 SELECT FROM TABLE(collection) 中的全局集合类型的匿名列指定别名

java - 集群 tomcat 的同步/互斥

php - 触发多个 Action 和循环

oracle - 如何仅在本地主机上运行 Oracle XE?

oracle - 什么是 PLSQL 中的 RESULT 关键字?

sql - 在 pl/sql 中插入触发器