【问题标题】:how to unlock locked tables explicitly in oracle如何在oracle中显式解锁锁定的表
【发布时间】:2015-04-22 16:04:42
【问题描述】:

我有一个主存储过程,它调用多个存储过程在多个表上写入数据,一次大约 9-10 个。一旦所有插入完成,所有插入都会有一个提交。
我想在单个子过程中使用数据并发和锁表,它没有任何提交,所以

LOCK TABLE table_name IN lock_mode

会起作用,但会保留该表,直到将其余数据插入在此之后调用的各个表中并调用最终提交或回滚,这不是一个好主意。我也没有打开dbms_lock

将锁定我的主存储过程中的所有表,还是锁定相应子存储过程中的表是唯一的选择?

我的主存储过程是这样的

PROCEDURE POPULATE_ALL(P_ASOFDATE DATE, P_ENTITY VARCHAR2) IS
    BEGIN
      POPULATE_ABC_BOOK(P_ASOFDATE);
      POPULATE_XYZ(P_ASOFDATE, P_ENTITY);
      POPULATE_DEF(P_ASOFDATE, P_ENTITY);
      POPULATE_AAA(P_ASOFDATE, P_ENTITY);
    commit;
    EXCEPTION
     WHEN OTHERS THEN
       rollback;
       P_ERROR := SQLERRM;
       RAISE_APPLICATION_ERROR(-20001,
                              '*** Unexpected Error in POPULATE_ALL -->' ||
                              P_ERROR);
   END POPULATE_ALL;

其中 POPULATE_XYZ 正在填充 XYZ 表。

【问题讨论】:

  • 你为什么要明确锁定表?我处理过很多 Oracle 系统,但我还没有看到显式表锁定有用的系统。 dbms_lock“打开”是什么意思?您是说出于某种原因不允许使用dbms_lock?为什么允许显式锁定表但不能获取用户定义的锁定?
  • 是的,我不允许使用dbms_lock
  • 你为什么要明确锁定表?为什么允许显式锁定表但不能获取用户定义的锁定?

标签: oracle stored-procedures concurrency


【解决方案1】:

看起来您根本不需要锁定。只需在没有任何显式锁定的情况下进行插入。

在事务处理过程中无法解锁表。这个操作在 Oracle 中没有任何意义;只有当数据库支持脏读时它才有用。表锁定仅在以下情况下完成

  • 提交,
  • 回滚或
  • 在锁定建立之前回滚到保存点

已执行。

【讨论】:

  • 考虑场景...事务 T1 更改表 ABC 并将行值插入到 123...第二个事务 T2 进入,而 T1 仍在工作。 T2 更改为 789。T1 提交,一切都很好。 T2 发生异常并回滚。但由于 T2 将值更改为 789 并且 T1 已提交。表 ABC、123 或 789 中的值是多少?如果它是 789,那么数据将是错误的。请解释
  • @deejay - 我不关注。如果 T1 尚未提交插入,则 T2 看不到该行(它未提交),因此它不可能在 T1 提交之前更新它,因为直到那时它才能看到该行。
  • @deejay,你听过ACID吗? :) 您可以尝试重现这种情况,您会发现这是不可能的。事务 T2 在提交 T1 之前没有机会更新“行值”。
  • 嗯,我知道 ACID :) 并感谢您再次清除我。
  • 不客气。一般来说...锁定是一个重要而脆弱的领域。在您完全了解之前,不要尝试介绍自己的方法。如果您有疑问,请信任数据库或咨询高级开发人员。
最近更新 更多