oracle锁机制

来源:互联网 发布:js中换行符是哪个 编辑:程序博客网 时间:2024/05/01 10:23

 oracle的锁机制
       目的:为了对并发操作进行控制,对干扰进行封锁,保证数据的一致性和准确信。
 数据库锁分类:共享封锁、 独占封锁、 共享更新封锁

[b:8f4f63b9bb]封锁类型[/b:8f4f63b9bb]
  oracle  RDBMS的封锁类型有以下3类:
 1、内部级封锁:是用于保护oracle内部结构,由系统内部实现,用户不能访问。
 2、DDL级封锁(字典/语法分析封锁)
       DDL级封锁也有oracle RDBMS来控制,它用于保护数据字典和数据定义时的一致性和完整性。 它是系统对SQL定义语句语法分析时自动加锁,无须用户干预。其又分为3种类型的锁。
    (1)、字典操作锁:用语对字典操作时,锁住数据字典,此封锁是独占的,从而保护任何一个 时刻只能对一个字典操作。
    (2)、字典定义锁:用于防止在进行字典操作时又进行语法分析,这样可以避免在查询字典 的同时改动某个表的结构。
    (3)、表定义锁:用于一个SQL语句正当访问某个表时,防止字典中与该表有关的项目被修改。
 3、DML级封锁
      用于控制并发事务中的数据操纵,保证数据的一致性和完整性,其封锁对象可以是表或行。
      对用户的数据操纵,oracle可以自动为操作的数据进行封锁,但如果有操作权限,则为满足并发操纵的需要另外施加封锁。DML封锁可由一个用户进程以显示的方式加锁,也可以通过某些SQL语句隐含方式实现。
   DML也有3种封锁方式:
   (1)、共享封锁方式(SHARE)
         它是对表中所有数据进行封锁,用于保护查询数据的一致性,防止其他用户对已经封锁的表进行更新。其他用户可以
对其施加共享封锁,而不能施加独占方式的封锁,共享更新锁可以施加,但是不容许持有共享更新锁的进程做更新。
     共享方式的表封锁只能有用户有SQL语句来设置。
          [quote:04b72348bd]LOCK   TABLE   <表名>[,<表名>]...    
          IN   SHARE   MODE   [NOWAIT]    
          [/quote:04b72348bd]  
     若该封锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。    
 持有共享锁的事物,在出现如下条件之一时,便释放其共享锁:
     A:执行COMMIT或ROLLBACK。
     B:推出数据库(LOG OFF)
     C:程序停止运行。
   共享方式表封锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变。 
   (2)、独占封锁方式(EXCLUSIVE)
       独占方式表封锁是用于封锁表中的所有数据,拥有该独占方式表封锁的用户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何封锁(包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询该表。    
        独占方式的表封锁可通过如下的SQL语句来显示地获得:    
             LOCK   TABLE   <表名>[,<表名>]....    
             IN   EXCLUSIVE   MODE   [NOWAIT]     
      独占方式的表封锁也可以在用户执行DML语句INSERT、UPDATE、DELETE时隐含获得
     拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁:    
        A、执行COMMIT或ROLLBACK语句。    
        B、退出数据库(LOG   OFF)    
        C、程序停止运行。    

   (3)、共享更新封锁(SHARE UPDATE)
           它是对一个表的一行或多行进行封锁,表级封锁虽然保证了数据的一致性,但却减弱了操作数据的并行性。这个锁可以确保用户取得被更新的行到该进行更新这段时间 内不被其他用户所修改。所以这个锁既可以保证数据的一致性又能提高数据操作的并发性。
    数据库中可以通过两种方法来获得共享更新锁:
    A:执行SQL语句
         LOCK   TABLE   <表名>[,<表名>]....    
         IN   SHARE   UPDATE MODE   [NOWAIT]
    B:用如下的SELECT   ...FOR   UPDATE语句获得:    
         SELECT   <列名>[,<列名>]...    
         FROM   <表名>    
         WHERE   <条件>    
         FOR   UPDATE   OF   <列名>[,<列名>].....[NOWAIT]
    共享更新锁释放的条件:
       1、执行提交(COMMIT)语句;
       2、推出数据库;
       3、程序停止运行;
    注意:执行ROLLBACK操作时不能释放此锁    
 其中SHARE,EXCLUSIVE用于表封锁,SHARE   UPDATE用于行封锁
       可见ORACLE加锁机制,解决了并发事务的相容和互斥问题。相容保证事务的并发性,
互斥确保数据的一致性。
 [b:eee2798085]死锁[/b:eee2798085]  
   注意:封锁虽然能够有效的解决并发操作,但是任何资源的独占都有可能产生死锁,
        例如:有两个事务T1,T2,T1对数据A施加独占封锁,T2对数据B施加了独占封锁。再假设T1要对数据B加锁,由于B已被T2独占封锁,因此T1置于等待状态,等待B被释放;现在若T2也要对A进行封锁,由于A已被T1独占封锁,因此T2也被置于等待状态。这样就形成了两个事务相互等待的状态,而且永远不能结束,此种情况称为死锁。    
       值得高兴的是ORACLE系统中能自动发现死锁,并选择代价最小的,即完成工作量最少的事务予以撤消,
    释放该事务所拥有的全部锁,让其他事务继续工作下去。
 从系统性能上考虑,应该尽量减少资源竞争,增大吞吐量,因此用户在加锁时应该注意几点:
    1、对于UPDATE和DELETE操作,应只封锁要做改动的行,在完成修改后立即提交。  
    2、当多个事务正利用共享更新的方式进行更新,则不要使用共享封锁,而应采用共享更新封锁,这样其它用户就能使用行级锁,以增加并行性。    
    3、尽可能将对一个表的操作的并发事务施加共享更新锁,从而可提高并行性
    4、在应用负荷较高的期间,不宜对基础数据结构(表、索引、簇和视图)进行修改

下面介绍一下不加锁时会出现的问题:
1、丢失数据
   A、B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如定票系统。
2、脏读
   A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致
3、不可重复读
   A用户读取数据,随后B用户读出该数据并修改,此时A用户再读取数据时发现前后两次的值不一致

    

 

原创粉丝点击