oracle 锁

一直以来对oracle的锁都没搞清楚,这次借考OCA的机会弄了一下。

  

 实验如下(以下的结果是在oracle10g上测试的):

 1.insert  语句

     会话1--->

        insert into p(x) values(8); //表p就一个字段,number类型

        select * from v$lock where (type = 'TM' or type = 'TX') and sid = userenv('SID');

        (假设系统只有该用户)查询结果为:

        P表被锁住了,LMODE 3(TM锁:行排他锁),还有一个TX锁(LMODE=6)

     会话2--->

        如果这个时候另外一个用户登录,企图删除这个表:

        drop table user1.p;

        立刻抛出ora-00054的错误。

        如果插入同样的数据,则被阻塞,直到上个用户提交或者回滚

2.update  语句

    如果p表没有被c表作为外键关联,则和insert语句产生的锁是一样的。

    下面我们来看一下有外键关系的情况:

    假设现在有个c表关联了p表,p表的主键是c表的外键。假设现在c表有2条数据,对应p表的2条数据,p表6条数据。

    会话1--->

       update p set x=10 where x = 3;//假设该主键未被c表引用

       此时如果表c的外键没有索引,则c表不会被锁柱,否则c表被锁住了(LMODE=2:行共享锁)。为什么

       有了索引反而会锁住的呢?这个我也没搞明白。

       

       还有一种情况,如果我先往c表插入一条数据:

       insert into c(x) values(3);

 

     会话2--->

       delete from p where p.x = 6;

 

       这时候这个会话被阻塞,因为它要对c表加个LMODE=4的共享锁,但会话1已经对它进行行共享锁了。

       这个也是oracle产生死锁的主要原因(外键没有索引) 。如果我们在c表的外键加个索引,看看什么情况:

       delete from p where p.x = 6;

       0 rows deleted

       很明显,这个时候不会试图锁住c表。

       从上面的例子可以看出,删除主表的数据的时候(执行该DML语句的期间),如果子表外键没有索引,

       则会锁住子表(LMODE=4:共享锁)。

 

       ----------------------------------------------------------------------------------------------------------------   

                                                                         Lock  Lock Modes Permitted?  
SQL                        Mode  RS RX S  SRX X  
SELECT                           Y  Y  Y  Y  Y 
INSERT                       RX  Y  Y  N  N  N  
UPDATE                       RX  Y* Y* N  N  N 
DELETE                       RX  Y* Y* N  N  N 
SELECT.. FOR UPDATE OF..     RS  Y* Y* Y* Y* N 
LOCK TABLE <table_name> 
 IN ROW SHARE MODE           RS  Y  Y  Y  Y  N 
 IN ROW EXCLUSIVE MODE       RX  Y  Y  N  N  N 
 IN SHARE MODE               S   Y  N  Y  N  N 
 IN SHARE ROW EXCLUSIVE MODE SRX Y  N  N  N  N 
 IN EXCLUSIVE MODE           X   N  N  N  N  N  
 
RS: row share RX: row exclusive S: share 
SRX: share row exclusive X: exclusive  
 
* Waits if another transaction has a lock  

        -------------------------------------------------------------------------------------------------------------

       以上这段摘在oracle_locking文件,这里的S锁和SRX主要有什么区别呢?

       1.一个事务锁住A表(S锁)之后,其他事务也能对该表进行S锁,当且仅当只有自己对该表有S锁时候才能

          修改该表的数据。如果有多个事务都有该表的S锁,那谁都不能修改数据。只能等待其他事务结束。

       2.一个事务锁住A表(SRX锁)之后,其他事务不能再对它进行SRX锁,只有自己才能更新数据。

你可能感兴趣的:(oracle,sql,C++,c,C#)