Oracle锁2:DML操作和锁
来源:互联网 发布:仿08影院视频网站源码 编辑:程序博客网 时间:2024/06/06 04:52
Oracle为DML操作自动获取行锁和表锁,操作的类型决定了锁的行为,下面对DML操作锁的情况作了一个汇总:
SELECT
... FROM
table
...
——noneYYYYYINSERT
INTO
table
...YesSXYYNNNUPDATE
table
...YesSXY(注)Y(注)NNNMERGE
INTO
table
...YesSXYYNNNDELETE
FROM
table
...YesSXY(注)Y(注)NNNSELECT
... FROM
table
FOR
UPDATE
OF
...YesSXY(注)Y(注)NNNLOCK
TABLE
table
IN
...—— ROW
SHARE
MODE
SSYYYYNROW
EXCLUSIVE
MODE
SXYYNNNSHARE
MODE
SYNYNNSHARE
ROW
EXCLUSIVE
MODE
SSXYNNNNEXCLUSIVE
MODE
XNNNNN注:如果另一个事务和当前事务出现行冲突,则需要等待
下面阐述当行被查询和修改时会涉及到的锁。
当行被查询时的锁
一个查询可以直接通过SELECT查询数据,或者其它语句间接的查询数据,如:INSERT、MERGE、UPDATE和DELETE,其中只有INSERT操作不是必定会涉及到查询的。因为查询仅读数据,因此他们被其它DML语句干涉的可能性是最小的。
如果查询没有FOR UPDATE子句,则查询时:
1)查询不要求数据锁,因此,其它事务能查询和更新正在被查询的数据;
2)查询不必等待任何数据锁被释放,因此,查询总是能执行。一个例外是查询必须等待分布式事务的一些特定的数据锁。
如果查询没有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):
4)在同一个事务中,一个查询能看到先前的DML语句修改的行,但不能看到其它事务未提交的改变。
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语句修改的行,但不能看到其它事务未提交的改变。
0 1
- Oracle锁2:DML操作和锁
- Oracle DML和DDL锁的解决方法
- Oracle锁1:DML锁
- Oracle Locks之DML锁
- oracle视图的DML操作
- 操作数据库表的几个DML(Oracle)
- Oracle连接视图DML操作的限制
- oracle dml操作生成redo、undo测试
- Oracle连接视图DML操作的限制
- Oracle 视图可以DML操作的条件
- Oracle连接视图DML操作的限制
- Oracle-31-对视图DML操作
- Oracle操作语句之DML语句
- oracle 表DML操作特别卡
- ORACLE数据库数据操作语言DML
- 什么是Oracle Key-Preserved Table和什么样的视图可以进行DML操作
- oracle全攻略——查询优化,DDL和DML操作
- Oracle触发器2-DML触发器
- hdu 4453 Looploop(splay)
- 【MFC】打开文件的流程
- PHP 笔试题整理
- gcc编译链接动态库详解
- socket()参数详解
- Oracle锁2:DML操作和锁
- css - 用inline实现页面元素排列一行
- 使用HTML5 SVG绘制的多层饼形图(纯javascript)
- 对php的接口类与抽象类的理解
- 数据离散化
- IOS中类和对象还有,nil/Nil/NULL的区别
- iOS之扩展(extension)的使用
- java 适配器模式
- C++对字符串流的读写