暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 锁定断开表

askTom 2018-01-23
221

问题描述

嗨,汤姆,
我有这个问题:
我需要在两个断开连接的表中 “锁定更新” 记录。对于 “断开连接”,我的意思是两个没有任何关系的表,例如表EMPLOYEE和文件夹: 当我必须更新员工记录时,我必须更新一个文件夹记录,该文件夹记录与员工没有外键。

我的代码是这样的:

-----------------------------------------
PROCEDURE UpdateEmployee
IS
   CURSOR myCurE
        is select * from EMPLOYEE
           where id = 5
           for update;
   CURSOR myCurF
        is select * from FOLDER
           where id = 108
           for update;
BEGIN
    open myCurE;
    open myCurF;

    -- updating code here
    
    close myCurE;
    close myCurF;
    
    -- commit is in the calling procedure
END;
-----------------------------------------
复制


我认为我的代码是不安全的,因为两个表在不同的时刻被锁定,并且可能会发生死锁。
有没有一种方法可以一次锁定两个或多个断开连接的表中的记录?
我考虑使用完全联接,但它给了我ORA-02014的错误

提前感谢您的帮助


专家解答

表格之间有外键吗?如果是这样,那么您确实可以锁定联接,例如

SQL> select * from emp, dept where emp.deptno = dept.deptno for update;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO     DEPTNO DNAME          LOC
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ---------- -------------- -----------
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10         10 ACCOUNTING     NEW YORK
      7839 KING       PRESIDENT            17-NOV-81       5000                    10         10 ACCOUNTING     NEW YORK
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10         10 ACCOUNTING     NEW YORK
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20         20 RESEARCH       DALLAS
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20         20 RESEARCH       DALLAS
      7876 ADAMS      CLERK           7788 12-JAN-83       1100                    20         20 RESEARCH       DALLAS
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20         20 RESEARCH       DALLAS
      7788 SCOTT      ANALYST         7566 09-DEC-82       3000                    20         20 RESEARCH       DALLAS
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30         30 SALES          CHICAGO
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500                    30         30 SALES          CHICAGO
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30         30 SALES          CHICAGO
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30         30 SALES          CHICAGO
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30         30 SALES          CHICAGO
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30         30 SALES          CHICAGO
      
SQL> select  l.type,
  2          o.name
  3  from  v$lock l, sys.obj$ o
  4  where l.id1 = o.obj#
  5  and l.type in ('TM','TX');

TY NAME
-- ------------------------------
TM EMP
TM DEPT

复制


如果不是,那么确保 * 每个人 * 使用您的UpdateEmployee过程确实成为您的责任,即,在锁定表时,您总是先锁定EMPLOYEE,然后再锁定文件夹。同样,如果您有一个仅锁定文件夹的进程,那么它将不允许随后调用另一个可能锁定EMPLOYEE的例程。

另一个要考虑的选项是NOWAIT锁,这样您就可以安全地将错误返回给调用者,而不是运行死锁的风险。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论