Oracle数据库中锁定的标准别保证了(jin)最大可能的q发U别也就是说,如果某个?x)话正在更新一条记?那么只有q条记录?x)被锁?此外,锁定q条记录是ؓ(f)?jin)防止其他?x)话对其进行更?其他?x)话可以随时执行d操作.只有在用commit或rollback命o(h)l束事务之后,锁定才会(x)被解?q种锁定是一?#8221;排他?#8221;:在指定记录上h排他锁的W一个会(x)话会(x)得到q个锁定,其他h对该记录q行写访问的?x)话则必ȝ?虽然q条记录已通过锁定?x)话q行?jin)更?但是对其q行读访问你是被允许?而且l常?x)出现这U情?,q且q些L作会(x)涉及(qing)撤销数据的?从而确保都?x)回q不?x)看CQ何未被提交的变化对于一条记录或一个完整表上的一个排他锁来说,每次只能有一个会(x)话可以获得这个排他锁,不过许多?x)话可以同时获得相同对象上?#8221;׃n?#8221;.在一条记录上讄׃n锁毫无意?其原因在于锁定一条记录的唯一目的是不允许其他会(x)话更改它.׃n锁被|于整个表上,同时许多?x)话可以获得同一个表上的׃n?在一个表上放|共享锁的目的是Z(jin)防止另一个会(x)话获得这个表上的排他?在已存在׃n锁的情况下无法再获得排他?.在表上防止排他锁是需要执行DDL语句.如果其他M?x)话已经在一个表上放|了(jin)׃n?那么我们无法执行修Ҏ(gu)个对象的语句(例如删除q个表的某一?.
Z(jin)在记录上执行DML语句,当前?x)话必须获取待更新记录上的排他锁以?qing)包含q些记录的表上的׃n?如果另一个会(x)话已l获取了(jin)待更新记录上的排他锁,那么当前?x)话被挂v,直至使用COMMIT或ROLLBACK命o(h)解除q些锁定,如果另一个会(x)话已l获取了(jin)待修改记录的表上的共享锁以及(qing)其他记录上的排他?那么׃存在M问题.一个表上的排他锁会(x)锁定q个?但是,如果不需要执行DDL语句,那么我们可以不锁定整个表的默认锁定机制.
提示:只有在特别请求ƈ且编Eh员具有充分理q情况?才可以要求在整个表上攄排他?
DML锁与DDL?/strong>
所有DML语句都至需要两U锁?受媄(jing)响记录上的排他锁,以及(qing)包含受媄(jing)响记录的表上的共享锁.排他锁能够防止其他会(x)话干预指定的记录,而共享锁则能够阻止其他会(x)话用DDL语句修改表的定义.q两U锁定会(x)被自动请?如果某条DML语句在指定记录上无法获取所需的排他锁,那么q条语句?x)被挂v直至获得所需的排他锁.
执行DDL命o(h)需要用所涉及(qing)对象上的排他?只有在针Ҏ(gu)定表的所有DML事务l束,q且记录上的排他锁以?qing)表上的׃n锁都被解除之?我们才可以获得执行DDL命o(h)所需的排他锁,MDDL语句所需的排他锁都是被自动请求的.但是,如果无法获取所需的排他锁(通常是因为其他会(x)话已l获得用于DML语句的共享锁),那么DDL语句׃(x)׃错误立即l止.
例子:
1. 使用SQL*PLUS,作ؓ(f)用户SYSTEMq接数据?
2. 创徏一个表,q且在这个表中插入一条记?
>create table t1(c1 number);
>insert into t1 values(1);
>commit;
3.再次使用SQL*PLUSq作为用户SYSTEMq行q接,从而打开另一个会(x)?
4.在第一个会(x)话中执行一个DML命o(h),q个命o(h)?x)在插入的记录上攄一个排他锁,同时q(sh)(x)在创建的表上攄一个共享锁.
>update table t1 set c1=2 where c1=1;
5.如下所C?在第二个?x)话中执行第一条针Ҏ(gu)的DDL语句.
>alter table t1 add(c2 date);
error at line 1:
ora-00054:resource busy and acquire with nowait specified
因ؓ(f)DDL语句需要表上的排他?而这与DML语句已在表上攄?jin)共享锁相冲H?所以试囑֜表中插入一个列的这条DDL语句?x)失?需要注意的?在类似情况下,DML语句?x)等待ƈ不断q行试,直至获得其所需的锁(换句话说是挂v);而DDL语句则会(x)׃错误立即l止.
6.在第一个会(x)话中,提交当前事务
>commit;
7.在第二个?x)话?重新执行步骤5.此时,因ؓ(f)不纯在与DDL排他锁相冲突的DML׃n?因此DDL语句成功的执行.
8.在第一个会(x)话中 ,锁定整个?
>lock table t1 in exclusive mode;
9.在第二个?x)话?插入一条记?此时,q个?x)话被挂v.
>insert into t1 values (1,sysdate);
10.在第一个会(x)话中,通过执行COMMIT命o(h)解除整个表上的锁?需要注意的?ROLLBACK命o(h)也可以实现相同的目的.
>commit;
11.W二个会(x)话会(x)释放q且现在?x)完成插入操?随后,执行COMMIT命o(h),l止当前事务斌且解除该记录上的排他锁.
关于如何解决死锁的问?
Q?查哪个过E被?br />
查V$DB_OBJECT_CACHE视图:
SELECT * FROM V$DB_OBJECT_CACHE WHERE OWNER=''q程的所属用?' AND LOCKS!=''0'';
2. 查是哪一个SID,通过SID可知道是哪个SESSION.
查V$ACCESS视图:
SELECT * FROM V$ACCESS WHERE OWNER=''q程的所属用?' AND NAME=''刚才查到的过E名
版权归原作者和各发布网站所有,此文章仅供学?fn)参考之?/em>