如果你有两个会话,每个会话都持有另一个会话想要的资源,此时就会出现死锁(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) 。
分享到:
相关推荐
【Oracle死锁的分类及其模拟】这篇博客主要探讨了Oracle数据库中的死锁问题,包括死锁的基本概念、分类以及如何进行模拟。以下是该主题的详细解释: **死锁概述** 死锁是数据库系统中常见的问题,它发生在两个或多...
oracle查询死锁语句,并能根据根据ID值杀死锁表的进程!
oracle死锁问题查询代码,仅供参考,有问题大家一起交流
### 一、理解Oracle死锁 #### 1.1 定义 死锁通常发生在两个或更多的事务试图同时锁定同一资源但以不同的顺序进行时。例如,事务A已经获得了资源X的锁,并尝试获取资源Y的锁;与此同时,事务B已经获得了资源Y的锁,...
关于Oracle数据库死锁问题的研究与讨论
然而,在高并发的业务环境中,ORACLE表的死锁问题却时常困扰着数据库管理员(DBA)。死锁,作为数据库操作中的一种特殊现象,是指两个或更多的事务在等待对方释放资源时陷入无限等待的状态,从而导致所有涉及的事务...
Oracle数据库在运行过程中,可能会遇到一种情况,那就是“表死锁”,这会导致多个事务相互等待对方释放资源,从而无法继续执行。死锁不仅影响数据库的正常运行,还可能导致数据一致性问题。本文将深入探讨Oracle表...
为了有效应对Oracle数据库中的死锁问题,我们可以使用以下SQL查询语句来进行死锁检测: ```sql SELECT bs.username "BlockingUser", ws.username "WaitingUser", bs.SID "SID", ws.SID "WSID", bs.serial# ...
### Oracle死锁原因及解决办法 #### 一、Oracle死锁概述 在Oracle数据库系统中,死锁是一种常见的并发问题,它会导致多个事务之间互相等待对方释放资源而无法继续执行,最终导致整个系统的运行效率降低甚至停滞。...
#### 四、Oracle死锁检测与处理 1. **检测死锁**:Oracle数据库能够自动检测死锁,并在检测到死锁后采取措施。默认情况下,Oracle会随机选择一个事务作为受害者并回滚它,从而解决死锁问题。此外,还可以使用`V$...
Oracle数据库死锁问题研究.pdf
#### 一、Oracle死锁的查找方法 ##### 1. 使用V$DB_OBJECT_CACHE视图 可以通过查询V$DB_OBJECT_CACHE视图来获取有关锁定对象的信息,进而发现可能存在的死锁情况。具体的SQL语句如下: ```sql SELECT * FROM V$DB...
Oracle数据库解决死锁是指在Oracle数据库中出现的死锁问题,通过使用PL/SQL语句手动解决死锁问题。死锁是当多个事务在等待其他事务释放资源时,导致系统无法继续执行的现象。 在Oracle数据库中,死锁可能是由多种...
Oracle数据库死锁是数据库系统中常见的问题,它发生在两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象。当这种情况发生时,如果没有外力干预,这些事务都将无法继续执行,形成一种僵局。了解如何...
在Oracle数据库系统中,死锁是指两个或多个...综上所述,处理Oracle死锁需要深入了解数据库的内部机制,并结合适当的监控和预防措施。通过有效的诊断和管理,我们可以减少死锁的发生,从而提高数据库的性能和可用性。
### Oracle中关于死锁的处理 #### 死锁概述 在Oracle数据库中,死锁是一种常见但必须妥善处理的问题。当两个或多个事务互相等待对方释放资源时就会发生死锁。这种情况下,没有一个事务能够继续执行,直到系统采取...
oracle死锁表后处理是指在oracle数据库中处理死锁表的各种方法和技巧。oracle死锁表后处理是数据库管理员和开发人员需要掌握的重要技能,旨在解决oracle数据库中出现的死锁问题,确保数据的一致性和安全性。 ...
在 Oracle 中,死锁是指两个或多个会话在等待对方释放资源,从而导致互相阻塞的情况。死锁可能会导致数据库性能下降,甚至崩溃。因此,解决死锁问题是非常重要的。 解决 Oracle 杀死死锁进程的步骤: 1. 查找被...
以下将详细阐述如何通过一系列步骤有效地关闭Oracle死锁进程,以及如何释放状态为killed的session。 ### 一、识别死锁进程 #### 查找被锁定的过程 首先,我们需要确定哪些进程正处于死锁状态。这可以通过查询`V$...
Oracle数据库出现死锁的时候可以按照以下处理步骤加以解决: 第一步:尝试在sqlplus中通过sql命令进行删除,如果能够删除成功,则万事大吉!但通常情况下,出现死锁时,想通过命令行或者通过Oracle的管理工具删除有...