oracle中的锁机制

转载自:http://blog.csdn.net/xiong2009/article/details/871090

 

 

锁是一种机制,是用来管理对一个共享资源的并行访问。
解停? 只有对资源进行并行访问时才会用到锁,但单个户模式下的数据库是不需要锁的。所以锁的目的就是在多个用户并行访问数据库时为了保证数据的一致和准确性采用的一种保护机制。几乎所有的数据库都采用了锁的机制,但其实现机制却有很大的却别。Oracle在锁的处理上较SYBASE和informix有着明显的优势,特别是在行级锁的处理上,基本上算是完美。

封锁问题
一个典型的程序设计缺陷例子。
A:用户1检索到一行数据,并准备修改。
B:用户2检索到相同的数据。
C:用户2删除了这一行,并提交。
D:用户修改那一行,并提交,结果程序报错,该行不存在。
用户抱怨开发商,开发商认为是用户人为因素造成。

分析
当用户1通过程序从数据库中提取出自己想要修改的记录时,该记录并没有锁定,此时用户2用同样的条件检索到该行,并删除,提交导致该行不复存在,此时用户1对检索到的行修改后提交时,由于该行已经被删除,导致用户操作失败。从而对软件失去信心。
解决方法
在对该行进行修改之前,对该行锁定,防止其他人对该行进行dml操作。select * from tab for update nowait;
此时数据库将在该行上建立一个行级排它锁,直到等到一个commit或者rollback时才释放。

一、悲观封锁
锁在用户修改之前就发挥作用:
Select ..for update(nowait)
Select * from tab1 for update
用户发出这条命令之后,oracle将会对返回集中的数据建立行级封锁,以防止其他用户的修改。
如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。
1:对返回结果集进行update或delete操作会发生阻塞。
2:对该表进行ddl操作将会报:Ora-00054:resource busy and acquire with nowait specified.

原因分析
此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback.
同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.

二、乐观封锁
乐观的认为数据在select出来到update进取并提交的这段时间数据不会被更改。这里面有一种潜在的危险就是由于被选出的结果集并没有被锁定,是存在一种可能被其他用户更改的可能。因此Oracle仍然建议是用悲观封锁,因为这样会更安全。

阻塞

定义:
当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。4个常见的dml语句会产生阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE

INSERT

Insert发生阻塞的唯一情况就是用户拥有一个建有主键约束的表。当2个的会话同时试图向表中插入相同的数据时,其中的一个会话将被阻塞,直到另外一个会话提交或会滚。一个会话提交时,另一个会话将收到主键重复的错误。回滚时,被阻塞的会话将继续执行。

UPDATE 和DELETE当执行Update和delete操作的数据行已经被另外的会话锁定时,将会发生阻塞,直到另一个会话提交或会滚。

Select …for update

当一个用户发出select..for update的错作准备对返回的结果集进行修改时,如果结果集已经被另一个会话锁定,就是发生阻塞。需要等另一个会话结束之后才可继续执行。可以通过发出select… for update nowait的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified.

死锁-deadlock

定义:当两个用户希望持有对方的资源时就会发生死锁.
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.
例子:
1:用户1对A表进行Update,没有提交。
2:用户2对B表进行Update,没有提交。
此时双反不存在资源共享的问题。
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
起因
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。

锁的分类


按封锁的对象可以分成:
DML lock
DDL lock

DML LOCK
DML锁是用来保护数据在被并行访问时数据的安全和一致性,按照限制级别的高低依次可以分成以下几种:
1:ROWLOCK(TX)
DML:insert,update,delete ,select …for update.
这些操作会在所操作的行上建立排它锁,直到所在的事物提交或会滚才释放。

2:table-lock(TM )
当一个事物在进行DML操作时,所在的事务会对所操作的表加表级锁,以保证在这个事务过程中表不被改变。
表级锁按照限制等级可以分成以下几类:
3:RS
Row share table lock
以下的操作会产生RS lock
Select * from tab for update.
LOCK TABLE table IN ROW SHARE MODE;
RS不允许的操作
LOCK TABLE table IN EXCLUSIVE MODE;

4:RX
Row Exclusive Table Locks
以下的操作会产生RS lock
1:INSERT,UPDATE ,DELETE
2:LOCK TABLE table IN ROW EXCLUSIVE MODE;
RX不允许的操作
LOCK TABLE table IN SHARE MODE;
LOCK TABLE table IN SHARE EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;

5:S
Share Table Locks
以下操作产生S lock.
LOCK TABLE table IN SHARE MODE;
S不允许的操作
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;
LOCK TABLE table IN ROW EXCLUSIVE MODE;

SRX
Share Row Exclusive Table Locks
以下操作产生SRX LOCK
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
SRX不允许的操作.
LOCK TABLE table IN SHARE MODE;
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE table IN ROW EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;
X
Exclusive Table Locks
一下操作产生X LOCK
LOCK TABLE table IN EXCLUSIVE MODE;
X不允许的操作
不允许所有的操作

posted @ 2013-04-25 10:04  小白快跑  阅读(307)  评论(0编辑  收藏  举报