码迷,mamicode.com
首页 > 数据库 > 详细

Oracle锁2:DML操作和锁

时间:2015-01-14 16:52:36      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:database   oracle   数据库   事务   

Oracle为DML操作自动获取行锁和表锁,操作的类型决定了锁的行为,下面对DML操作锁的情况作了一个汇总:

SQL Statement Row Locks Table Lock Mode RS RX S SRX X
SELECT ... FROM table... —— none Y Y Y Y Y
INSERT INTO table ... Yes SX Y Y N N N
UPDATE table ... Yes SX Y(注) Y(注) N N N
MERGE INTO table ... Yes SX Y Y N N N
DELETE FROM table ... Yes SX Y(注) Y(注) N N N
SELECT ... FROM tableFORUPDATEOF ... Yes SX Y(注) Y(注) N N N
LOCK TABLE tableIN ... ——            
ROW SHARE MODE   SS Y Y Y Y N
ROW EXCLUSIVE MODE   SX Y Y N N N
SHARE MODE   S Y N Y N N
SHARE ROW EXCLUSIVE MODE   SSX Y N N N N
EXCLUSIVE MODE   X N N N N N

注:如果另一个事务和当前事务出现行冲突,则需要等待

下面阐述当行被查询和修改时会涉及到的锁。

当行被查询时的锁

一个查询可以直接通过SELECT查询数据,或者其它语句间接的查询数据,如:INSERT、MERGE、UPDATE和DELETE,其中只有INSERT操作不是必定会涉及到查询的。因为查询仅读数据,因此他们被其它DML语句干涉的可能性是最小的。
如果查询没有FOR UPDATE子句,则查询时:
1)查询不要求数据锁,因此,其它事务能查询和更新正在被查询的数据;
2)查询不必等待任何数据锁被释放,因此,查询总是能执行。一个例外是查询必须等待分布式事务的一些特定的数据锁。

当行被修改时的锁

一些数据库使用一个内存中的列表来维护锁,但Oracle数据库存储锁信息在数据块中,信息包含了被锁的行,每个行锁仅影响一行数据。
Oracle数据库为行锁的获取使用了一个队列机制,如果一个事务请求一个行锁,并且行未被锁,那么事务获取行的数据块的一个锁,事务自身会在数据块头的interested transaction list(ITL)区域放一个条目,被事务修改的每一行都指向ITL中存储的事务ID的一个拷贝,因此,被单个事务修改的在同一块中的100行数据会要求100个行锁,但是所有100行都引用同一个事务ID。
当事务结束时,事务ID保留在数据块头的ITL区域中。如果一个新的事物想修改一行,那么它使用事务ID判断该锁是否是激活的,如果锁是激活的,那么新事务的session会请求在锁被释放时被通知,否则,新事务获取锁。
INSERT、UPDATE、DELETE和SELECT ... FOR UPDATE将满足:
1)使用这些DML操作的事务将在修改的行上请求排它行锁,因此,其它事务不能更新或者删除锁定的行,直到事务commit或者roll back;
2)除了行锁,使用这些DML操作的事务至少需要请求一个子排它表锁(subexclusive table lock,SX)。如果事务已经拥有了一个S、SRX或者X表锁(比SX锁有更强的限制),那么SX锁不被需要;如果事务已经拥有了一个SS锁,那么Oracle数据库自动转换SS锁到SX锁;
3)除非涉及的行被修改,事务不会对任何子查询或者隐含的子查询涉及的行加行锁;例如下面的update操作,使用那个了一个子查询(括号中的部分)和隐含子查询(WHERE a > 5):
UPDATE t SET x = ( SELECT y FROM t2 WHERE t2.z = t.z ) WHERE a > 5;
事务将不会对子查询(SELECT y FROM t2 WHERE t2.z = t.z)涉及的行加锁。
4)在同一个事务中,一个查询能看到先前的DML语句修改的行,但不能看到其它事务未提交的改变。

Oracle锁2:DML操作和锁

标签:database   oracle   数据库   事务   

原文地址:http://blog.csdn.net/tomato__/article/details/42711111

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!