- 浏览: 90498 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
zuowoziji123:
跟thinking in java里写的一模一样 晕
匿名内部类的初始化 -
hbyandy:
...
组合模式 -
speedup:
jvmlover 写道zwzm85 写道淘宝研究生是6k--8 ...
阿里巴巴和淘宝的校园应聘经历 -
sdh5724:
30以后的技术人员才是真正的在玩技术, 公司投资那么多IT设备 ...
阿里巴巴和淘宝的校园应聘经历 -
former:
我觉得:
"30岁转行"这句话也许你没有说 ...
阿里巴巴和淘宝的校园应聘经历
6.1 什么是锁?
锁(lock)机制用于管理对共享资源的并发访问。
首先,所有数据库本质上都不同。其次,学习每一个新数据库时,应该假设自己从未使用过数据库。在一个数据库中能做的事情在另一个数据库中可能没有必要做,或者根本不能做。
在Oracle中,你会了解到:
l 事务是每个数据库的核心,它们是“好东西”。
l 应该延迟到适当的时刻才提交。不要太快提交,以避免对系统带来压力。这是因为,如果事务很长或很大,一般不会对系统有压力。相应的原则是:在必要时才提交,但是此前不要提交。事务的大小只应该根据业务逻辑来定。
l 只要需要,就应该尽可能长时间地保持对数据所加的锁。这些锁是你能利用的工具,而不是让你退避三舍的东西。锁不是稀有资源。恰恰相反,只要需要,你就应该长期地保持数据上的锁。锁可能并不稀少,而且它们可以防止其他会话修改信息。
l 在Oracle中,行级锁没有相关的开销,根本没有。不论你是有1个行锁,还是1 000 000个行锁,专用于锁定这个信息的“资源”数都是一样的。当然,与修改1行相比,修改1 000 000行要做的工作肯定多得多,但是对1 000 000行锁定所需的资源数与对1行锁定所需的资源数完全相同,这是一个固定的常量。
l 不要以为锁升级“对系统更好”(例如,使用表锁而不是行锁)。在Oracle中,锁升级(lock escalate)对系统没有任何好处,不会节省任何资源。也许有时会使用表锁,如批处理中,此时你很清楚会更新整个表,而且不希望其他会话锁定表中的行。但是使用表锁绝对不是为了避免分配行锁,想以此来方便系统。
l 可以同时得到并发性和一致性。每次你都能快速而准确地得到数据。数据读取器不会被数据写入器阻塞。数据写入器也不会被数据读取器阻塞。这是Oracle与大多数其他关系数据库之间的根本区别之一。
6.2 锁定问题
6.2.1 丢失更新
6.2.2 悲观锁定
悲观锁定(pessimistic locking)仅用于有状态(stateful)或有连接(connected)环境,也就是说,你的应用与数据库有一条连续的连接,而且至少在事务生存期中只有你一个人使用这条连接。除了简单地查询值并验证数据尚未修改外,我们要使用FOR UPDATE NOWAIT锁定这一行。
6.2.3 乐观锁定
第二种方法称为乐观锁定(optimistic locking),即把所有锁定都延迟到即将执行更新之前才做。
1. 使用版本列的乐观锁定
这是一个简单的实现,如果你想保护数据库表不出现丢失更新问题,应对每个要保护的表增加一列。这一列一般是 NUMBER 或DATE/TIMESTAMP 列,通常通过表上的一个行触发器来维护。每次修改行时,这个触发器要负责递增 NUMBER 列中的值,或者更新DATE/TIMESTAMP列。
2. 使用校验和的乐观锁定
这与前面的版本列方法很相似,不过在此要使用基数据本身来计算一个“虚拟的”版本列。
3. 使用 ORA_ROWSCN 的乐观锁定
从 Oracle 10g Release 1开始,你还可以使用内置的 ORA_ROWSCN 函数。它的工作与前面所述的版本列技术很相似,但是可以由Oracle自动执行,而不需要在表中增加额外的列,也不需要额外的更新/维护代码来更新这个值。除非你创建表时支持在行级维护ORA_ROWSCN,否则Oracle会在块级维护。也就是说,默认情况下,一个块上的多行会共享相同的 ORA_ROWSCN 值。如果更新一个块上的某一行,而且这个块上还有另外50行,那么这些行的ORA_ROWSCN也会推进。这往往会导致许多假警报,你认为某一行已经修改,但实际上它并没有改动。如果要在行级上维护则需要在建表时加上ROWDEPENDENCIES子句。
另外可以把SCN转换为墙上时钟,但有一些限制:数据库的正常运行时间只有5天左右。如:select scn_to_timestamp(ora_rowscn) from dept;
6.2.4 乐观锁定还是悲观锁定?
6.2.5 阻塞
如果一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking)。这样一来,请求的会话会被阻塞,它会“挂起”,直至持有锁的会话放弃锁定的资源。几乎在所有情况下,阻塞都是可以避免的。实际上,如果你真的发现会话在一个交互式应用中被阻塞,就说明很有可能同时存在着另一个 bug,即丢失更新,只不过你可能没有意识到这一点。也就是说,你的应用逻辑有问题,这才是阻塞的根源。
数据库中有5条常见的DML语句可能会阻塞,具体是:INSERT、UPDATE、DELETE、MERGE和SELECT FOR UPDATE。
1. 阻塞的 INSERT
最常见的情况是,你有一个带主键的表,或者表上有惟一的约束,但有两个会话试图用同样的值插入一行。
一种解决方法是:创建一个触发器,在插入前,把插入行的主键散列到一个数字上,然后用一个排他锁把这个数字锁住,这样另一个人在插入相同的行时得不到这个锁,而收到一个错误,从而得知正试图插入相同行。
最后,还要记住,尽管Oracle有无限多个行级锁,但是 enqueue锁(这是一种队列锁)的个数则是有限的。如果在会话中插入大量行,而没有提交,可能就会发现创建了太
多的 enqueue 队列锁,而耗尽了系统的队列资源(超出了 ENQUEUE_RESOURCES 系统参数设置的最大值),因为每行都会创建另一个enqueue锁。如果确实发生了这种情况,就需要增大ENQUEUE_RESOURCES参数的值。还可以向触发器增加一个标志,允许打开或关闭这种检查。例如,如果我准备插入数百条或数千条记录,可能就不希望启用这个检查。
问题:什么是enqueue锁?为什么插入时每行都会创建另一个enqueue锁?ENQUEUE_RESOURCES 系统参数是个什么参数?
2. 阻塞的 Merge、Update 和 Delete
在一个交互式应用中,可以从数据库查询某个数据,允许最终用户处理这个数据,再把它“放回”到数据库中,此时如果 UPDATE 或DELETE阻塞,就说明你的代码中可能存在一个丢失更新问题(如果真是这样,按我的说法,就是你的代码中存在bug) 。你试图UPDATE
(更新)其他人正在更新的行(换句话说,有人已经锁住了这一行)。通过使用SELECT FOR UPDATE NOWAIT查询可以避免这个问题,这个查询能做到:
l 验证自从你查询数据之后数据未被修改(防止丢失更新)。
l 锁住行(防止UPDATE或DELETE被阻塞)。
6.2.6 死锁
根据我的经验,导致死锁的头号原因是外键未加索引(第二号原因是表上的位图索引遭到并发更新,这个内容将在第 11 章讨论)。
在以下两种情况下,Oracle在修改父表后会对子表加一个全表锁:
l 如果更新了父表的主键(倘若遵循关系数据库的原则,即主键应当是不可变的,这种情况就很少见),由于外键上没有索引,所以子表会被锁住。
l 如果删除了父表中的一行,整个子表也会被锁住(由于外键上没有索引)。
在以下情况下,未加索引的外键也可能带来问题:
l 如果有ON DELETE CASCADE,而且没有对子表加索引:例如,EMP是DEPT的子表,DELETE DEPTNO = 10应该CASCADE(级联)至 EMP[4]。如果 EMP中的 DEPTNO没有索引,那么删除 DEPT 表中的每一行时都会对 EMP 做一个全表扫描。这个全表扫描可能是不必要的,而且如果从父表删除多行,父表中每删除一行就要扫描一次子表。
l 从父表查询子表:再次考虑 EMP/DEPT 例子。利用 DEPTNO 查询 EMP 表是相当常见的。如果频繁地运行以下查询(例如,生成一个报告) ,你会发现没有索引会使查询速度变慢:
select * from dept, emp where emp.deptno = dept.deptno and dept.deptno = :X;
那么,什么时候不需要对外键加索引呢?答案是,一般来说,当满足以下条件时不需要加索引:
l 没有从父表删除行。
l 没有更新父表的惟一键/主键值(当心工具有时会无意地更新主键!)。
l 没有从父表联结子表(如DEPT联结到EMP)。
如果满足上述全部 3 个条件,那你完全可以跳过索引,不需要对外键加索引。如果满足以上的某个条件,就要当心加索引的后果。这是一种少有的情况,即Oracle“过分地锁定了”数据。
6.2.7 锁升级
如果数据库认为锁是一种稀有资源,而且想避免锁的开销,这些数据库中就会频繁使用锁升级。如果数据库支持锁升级,就说明这个数据库的锁定机制中存在某些内部开销,而且管理数百个锁需要做大量的工作。在Oracle中,1个锁的开销与1 000 000个锁是一样的,都没有开销。
注意:Oracle不会升级锁,从来不会。但是它会执行锁转换(lock conversion)或锁提升(lock promotion) ,这些词通常会与锁升级混淆。“锁转换”和“锁提升”是同义词。Oracle一般称这个过程为“锁转换”。
Oracle会尽可能地在最低级别锁定(也就是说,限制最少的锁),如果必要,会把这个锁转换为一个更受限的级别。
发表评论
-
ORACLE 命令大全(2)
2010-08-08 16:42 1546一些常用的内置程序包: DBMS_OUTPUT 包输出 PL ... -
RMAN 命令拼凑版
2010-08-08 11:08 972http://blog.chinaunix.net/u1/4 ... -
ORACLE 命令大全(1)
2010-08-08 10:54 1592内容包括三大项: 1.o ... -
Oracle进程类别
2009-09-28 16:40 2085Oracle进程类别 n Oracle实 ... -
Oracle内存结构与管理(2)
2009-09-28 16:38 960自动SGA内存管理(ASMM): 要使用自动管理,需要设置参 ... -
Oracle内存结构与管理(1)
2009-09-28 16:34 1607Oracle内存结构与管理 内存结构 SGA(Sys ... -
Oracle触发器增量提取
2009-09-23 10:59 1784--insert触发器提取增量 --delete触发器提取增 ... -
9i SQL notes
2009-09-12 21:59 1317General functions:– NVL– NVL2– ... -
ORACLE 死锁实验
2009-07-25 17:02 822环境: DB: ORACLE 10.2 OS : RHE ... -
oracle启动
2009-07-23 09:10 961oracle启动的状态 学 ... -
Oracle 临时表
2009-07-16 11:22 1387Oracle 临时表 临时表(Temporary ta ... -
ORA-30036 错误重演实验
2009-07-15 21:01 2612实验步骤: 1. 建立一个很小的UNDO表空间,把系统当前的 ... -
Redo 与 Undo (2)
2009-07-14 20:37 14449.4.6 日志竞争 l redo放在 ... -
Redo 与 Undo (1)
2009-07-14 20:33 1657通常对undo有一个误解, ... -
事 务
2009-07-12 10:48 1114事 务 Oracle中的事务体现了所有必要的ACID ... -
并发与多版本
2009-07-11 19:33 1297并发与多版本 7.1 ... -
Oracle 锁(2)
2009-07-11 15:03 14656.3 锁类型 Oracle中主要有3类锁,具体是: ... -
Oracle进程类别(2)
2009-07-09 22:54 1488后台进程 可以使用一个V$视图查看所有可能的Oracl ... -
Oracle进程类别(1)
2009-07-09 22:48 963Oracle进程类别 n Oracle实 ... -
Oracle内存结构与管理
2009-07-07 21:19 1587Oracle内存结构与管理 内存结构 SGA(Sys ...
相关推荐
### Oracle的锁表与解锁:深入理解与操作 在Oracle数据库管理中,锁是一个至关重要的概念,用于控制多个用户或进程对数据的并发访问,确保数据的一致性和完整性。锁可以分为行级锁(Row Level Lock)和表级锁...
表1:Oracle的TM锁模式 锁模式 锁描述 解释 SQL操作 0 none 1 NULL 空 Select 2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share 3 SX(Row-X) 行级排它锁,...
Oracle数据库操作中,我们有时会用到锁表查询以及解锁和kill进程等操作,那么这些操作是怎么实现的呢?
在深入讨论Oracle解锁和死锁之前,我们首先需要了解Oracle数据库中的锁机制。 1. **共享锁(S)**:允许多个用户读取行,但不允许修改。 2. **排他锁(X)**:允许单个用户修改行,其他用户只能等待。 3. **共享更新锁...
### Oracle锁的概念与分类 #### 一、锁的基本概念 在Oracle数据库中,锁是一种用于管理并发事务的重要机制。通过锁机制,Oracle能够确保多用户环境下的数据一致性和完整性。简单来说,锁是为了防止多个用户同时...
oracle解锁语句,常用解锁语句,经过测试实用;oracle解锁语句,常用解锁语句,经过测试实用。
### Oracle 锁机制问题详解 #### 一、引言 在多用户数据库环境中,当多个用户尝试同时访问或修改同一份数据时,就需要通过锁机制来确保数据的一致性和完整性。Oracle 数据库提供了多种类型的锁来支持事务隔离级别,...
### 描述:“如果存储过程被锁住,可以使用这个存储过程解锁方法” #### 解析: 当遇到存储过程被锁定的情况时,通常可以通过查询`dba_ddl_locks`视图来查找锁定的详细信息。例如,要检查名为`prc_exec_day`的存储...
### Oracle锁表与解锁详解 在Oracle数据库管理中,锁是一种关键机制,用于控制多个用户对数据资源的并发访问,防止数据冲突和不一致。本文将深入探讨Oracle中检查锁表的方法以及如何对表进行解锁。 #### Oracle锁...
### Oracle数据库的锁类型详解 #### 一、引言 Oracle数据库作为企业级数据库解决方案的佼佼者,其锁机制是保障数据完整性和并发控制的关键技术之一。在Oracle数据库中,锁的使用是为了协调多个用户对同一数据资源...
oracle锁表和解锁语句示例。
### Oracle锁表查询详解 #### 一、Oracle锁机制简介 在Oracle数据库中,锁是一种重要的并发控制机制,用于管理多个用户对同一数据资源的访问。通过锁机制,Oracle能够确保数据的一致性和完整性,避免多用户操作时...
### 查看Oracle锁表 在Oracle数据库管理过程中,锁定机制是一项重要的功能,它用于确保数据的一致性和事务处理的安全性。当多个用户试图同时访问同一数据时,可能会出现并发问题,这时就需要通过锁定来控制对数据的...
Oracle数据库系统中,锁和表分区是两个关键的管理数据并发和优化性能的机制。首先,我们来深入了解锁的概念。 1. **锁定机制**:锁定是数据库管理系统中用于控制并发访问的一种方法,确保多用户环境下的数据完整性...
针对oracle数据库 解锁方法 ,个人使用 希望大家能够有所帮助
本文将深入探讨Oracle锁的类型、工作原理以及相关的管理工具。 一、Oracle锁的类型 1. 表级锁:Oracle中的表级锁主要有两种,即排他锁(Exclusive Locks, X locks)和共享锁(Shared Locks, S locks)。排他锁允许...
Oracle锁表后如何解锁 Oracle锁表是指在Oracle数据库中某个表被锁定,无法进行操作的情况。这种情况经常发生在多用户同时访问同一个表时,某个用户锁定了该表,导致其他用户无法访问该表。那么,在不知道谁锁的情况...