zoukankan      html  css  js  c++  java
  • oracle为什么尽量不要使用外键的最好理解

    对于死锁问题相信大家都是很头疼的,为什么不要使用外键呢?最简单的回答就是太容易产生死锁了。

    经过个人的测试,我发现外键删除的时候,是按照表会话的顺序执行的,也就是说如果只有一个事务,只要子表删掉外键表的项,外键表就可以删除,但是如果同时有多个事务,这就难说了,具体举例子如下:

    首先我们创建表并创建数据,顺序执行如下代码:

    create table t_p (id number primary key, name varchar2(30)); 
    
    create table t_f (fid number, f_name varchar2(30), foreign key (fid) references t_p); 
    
    insert into t_p values (1, 'a'); 
    
    insert into t_f values (1, 'a'); 
    
    insert into t_p values (2, 'b'); 
    
    insert into t_f values (2, 'c'); 
    
    commit; 

     然后测试如下:我在本用户下(C##BENDIHELI)和System下开启两个sql工作表:

    其中在C##BENDIHELI记为sql1,system下记为sql2

    如果程序的执行顺序为:

    1.sql1:delete t_f where fid = 2; 

    2.sql2:delete c##bendiheli.t_f where fid = 1; 

    3.sql1:delete t_p where id = 2; 

    此时sql1等待,因为sql2未提交(这就是我理解的外键表需要找会话,本会话可以继续,如果有其他会话未提交,他就等待)

    4.sql2:delete c##bendiheli.t_p where id = 1; 

    此时sql2等待,因为sql1未提交

    现在的程序sql1的事务等待sql2的提交,sql2的事务等待sql1的提交,完了,锁住了。

    至于本人理解外键是按照会话寻找的原因是,即使我把2换成insert into c##bendiheli.t_f values(1,'duidu'),3仍然会等待,因为2没提交

    若我执行顺序为如下,则可以,这样就更能理解我的想法,就是外键按照非本会话的会话顺序执行

    1.sql1:delete t_f where fid = 2; 

    2.sql2:insert into c##bendiheli.t_f values(1,'duidu')

    3.sql1:delete t_p where id = 2; 

    此时sql1等

    4.sql2:commit;

    提交后sql1就不再等待

    解决方案:外键加索引

    create index ind_t_f_fid on t_f(fid);

    个人理解,这样就解决了外键按照会话找连接表的,而是通过索引来找,这样以来上方出现死锁的程序就不再出现死锁,因为这样在本事务内,直接找索引即可。 

    本文的理解借鉴于博主:https://blog.csdn.net/fenyu8/article/details/53811686

  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.2.25
    Elementary Methods in Number Theory Exercise 1.2.14
    图解欧几里德算法
    图解欧几里德算法
    Elementary Methods in Number Theory Exercise 1.2.14
    Android中的长度单位详解(dp、sp、px、in、pt、mm)
    分享下多年积累的对JAVA程序员成长之路的总结
    android异常之都是deamon惹的祸The connection to adb is down, and a severe error has occured.
    TomatoCartv1.1.8.2部署时报错
    JavaScript浏览器对象之二Document对象
  • 原文地址:https://www.cnblogs.com/ningxinjie/p/12765483.html
Copyright © 2011-2022 走看看