oracle中的死锁

如果你有两个会话,每个会话都持有另一个会话想要的资源,此时就会出现死锁(deadlock)
数据库中有两个表A和B,我们打开两个sqlplus会话,在会话1中更新A,在会话2中更新B,这时候如果在B中更新A,就会阻塞,因为会话1已经锁定了A,不过这不是死锁,只是一个阻塞,如果会话1提交或者回滚事务,则样会话2还可以继续。
这时候会话1,试图更新表B,这就会产生一个死锁。要在这两个会话中选择一个作为“牺牲
品”,让它的语句回滚。例如,会话B中对表A 的更新可能回滚,得到以下错误:
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

1。导致死锁的头号原因是外键未加索引(第二号原因是表上的位图索引遭到并发更新,
这个内容将在第11章讨论) 。在以下两种情况下,Oracle在修改父表后会对子表加一个全表锁:
如果更新了父表的主键(倘若遵循关系数据库的原则,即主键应当是不可变的,这种情况就很
少见),由于外键上没有索引,所以子表会被锁住。
2。如果删除了父表中的一行,整个子表也会被锁住(由于外键上没有索引)。

在Oracle9i及以上版本中,这些全表锁都是短期的,这意味着它们仅在DML操作期间存在,而不是
在整个事务期间都存在。即便如此,这些全表锁还是可能(而且确实会)导致很严重的锁定问题。
为了说明第二点
例:
建表P create table p ( x int primary key );
建表C,引用P主键: create table c ( x references p )
insert into p values ( 1 );
insert into p values ( 2 );
commit;
insert into c values ( 2 );
然后新启一个窗口:
delete from p where x = 1;
这时候这个会话就被阻塞了,因为在执行删除之前,试图对表C增加一个全表锁,现在,别的会话都不能对C表进行任何行执行DELETE、INSERT或UPDATE。

在这种情况下,如果EMP表有DEPT的一个外键,而且在EMP表的 DEPTNO列上没有任何索引,那么更新 DEPT 时整个 EMP 表都会被锁定。如果你使用了能生成 SQL 的工具,就一定要当心这一点。

删除父表中的一行可能导致子表被锁住,由此产生的问题更多。我已经说过,如果删除表 P 中的一行,那么在 DML 操作期间,子表 C 就会锁定,这样能避免事务期间对 C 执行其他更新(当然,这有一个前提,即没有人在修改C;如果确实已经有人在修改C,删除会等待) 。此时就会出现阻塞和死锁问题。如果有人抱怨说数据库中存 在死锁,我会让他们运行一个脚本,查看是不是存在未加索引的外键, 而且在99%的情况下都会发现表中确实存在这个问题。 只需对外键加索引,死锁(以及大量其他的竞争问题)都会烟消云散。


解决上述问题办法:

所以,这个脚本展示出,表 C 在列 X 上有一个外键,但是没有索引。通过对 X 加索引,就可以完全消除这个锁定问题。除了全表锁外,在以下情况下,未加索引的外键也可能带来问题:
1. 如果有ON DELETE CASCADE,而且没有对子表加索引:例如,EMP是DEPT的子表,DELETE
DEPTNO = 10应该CASCADE(级联)至EMP[4]。如果EMP中的DEPTNO没有索引,那么删
除DEPT表中的每一行时都会对EMP做一个全表扫描。这个全表扫描可能是不必要的,而且如果
从父表删除多行,父表中每删除一行就要扫描一次子表。
2.从父表查询子表:再次考虑 EMP/DEPT 例子。利用 DEPTNO 查询 EMP 表是相当常见的。如
果频繁地运行以下查询(例如,生成一个报告),你会发现没有索引会使查询速度变慢:
select * from dept, emp where emp.deptno = dept.deptno and dept.deptno = :X;


那么,什么时候不需要对外键加索引呢?答案是,一般来说,当满足以下条件时不需要加索引:
1.没有从父表删除行。
2.没有更新父表的惟一键/主键值(当心工具有时会无意地更新主键!)。
3.没有从父表联结子表(如DEPT联结到EMP) 。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值