zoukankan      html  css  js  c++  java
  • 浅谈数据库的锁

          数据库对于程序猿来 并不陌生,但是数据库的锁你知道多少?数据库的锁直接影响数据性能,在大并发的前提下,怎么保证数据不被死锁,提高数据库性能?如何加锁,何时加锁,加什么锁,你可以通过hint手工强行指定,但大多是数据库系统自动决定的。这就是为什么我们可以不懂锁也可以写SQL。

         下面我们来简单谈一谈数据库中的锁,以sqlserver 为例:

    数据库锁的种类:

    1.共享锁(Shared lock)

       何为共享锁,顾名思义意思就是资源共享,所以共享锁之间 是没有时间等待的可以同时执行一条或多条查询语句,共享锁是用来读的

            数据库规定同一资源上不能同时共存共享锁和排他锁。如果共享锁在前必须等共享锁执行完了才能加上排他锁

    2.排他锁(xlock) 

       排他锁,可以简单的理解为 有限定条件的 更新或者查询 如果对表强制加排它锁可以使用 手写关键字(xlock) 列入:select * from #t1 (xlock) 这里就强制给资源加上了排他锁,这样做的好处就是 我们在执行一些更新的sql语句时(列入事物,存储等),排除了死锁(holdlock)的可能

    3.更新锁(updlock)

            为解决死锁,引入更新锁。跟新锁意思是:“我现在只想读,你们别人也可以读,但我将来可能会做更新操作,我已经获取了从共享锁(用来读)到排他锁(用来更新)的资格”。一个事物只能有一个更新锁获此资格。    

    T1:
    begin
    select * from table(updlock)      (加更新锁)
    update table set column1='hello'  (重点:这里T1做update时,不需要等T2释放什么,而是直接把更新锁升级为排他锁,然后执行update)
    T2:
    begin
    select * from table               (T1加的更新锁不影响T2读取)
    update table set column1='world'  (T2的update需要等T1的update做完才能执行)

     共享锁和更新锁可以同时在同一个资源上。这被称为共享锁和更新锁是兼容的。
    
    

    4.死锁(holdlock)  holdlock  意思是加共享锁,直到事物结束才释放

    5.独占锁(Exclusive Locks)

    这个简单,即其它事务既不能读,又不能改排他锁锁定的资源
    列1
    T1:    update table set column1='hello' where id<1000
    T2:    update table set column1='world' where id>1000
    
    假设T1先达,T2随后至,这个过程中T1会对id<1000的记录施加排他锁.但不会阻塞T2的update。
    
    例2 (假设id都是自增长且连续的)
    T1:    update table set column1='hello' where id<1000
    T2:    update table set column1='world' where id>900
    
    如同例1,T1先达,T2立刻也到,T1加的排他锁会阻塞T2的update.

    6.意向锁(Intent Locks)

       意向锁就是说在屋(比如代表一个表)门口设置一个标识,说明屋子里有人(比如代表某些记录)被锁住了。另一个人想知道屋子
    里是否有人被锁,不用进屋子里一个一个的去查,直接看门口标识就行了。
       当一个表中的某一行被加上排他锁后,该表就不能再被加表锁。数据库程序如何知道该表不能被加表锁?一种方式是逐条的判断该
    表的每一条记录是否已经有排他锁,另一种方式是直接在表这一层级检查表本身是否有意向锁,不需要逐条判断。显然后者效率高。

    ----------------------------------------
    T1:    begin tran
           select * from table (xlock) where id=10  --意思是对id=10这一行强加排他锁
    T2:    begin tran
           select * from table (tablock)     --意思是要加表级锁
           
    假设T1先执行,T2后执行,T2执行时,欲加表锁,为判断是否可以加表锁,数据库系统要逐条判断table表每行记录是否已有排他锁,
    如果发现其中一行已经有排他锁了,就不允许再加表锁了。只是这样逐条判断效率太低了。
    
    实际上,数据库系统不是这样工作的。当T1的select执行时,系统对表table的id=10的这一行加了排他锁,还同时悄悄的对整个表
    加了意向排他锁(IX),当T2执行表锁时,只需要看到这个表已经有意向排他锁存在,就直接等待,而不需要逐条检查资源了。
    
     

    7.计划锁(Schema Locks)

      
    ----------------------------------------
    alter table .... (加schema locks,称之为Schema modification (Sch-M) locks
    
    DDL语句都会加Sch-M锁
    该锁不允许任何其它session连接该表。连都连不了这个表了,当然更不用说想对该表执行什么sql语句了。
    
    例15:
    ----------------------------------------
    用jdbc向数据库发送了一条新的sql语句,数据库要先对之进行编译,在编译期间,也会加锁,称之为:Schema stability (Sch-S) locks
    
    select * from tableA
    
    编译这条语句过程中,其它session可以对表tableA做任何操作(update,delete,加排他锁等等),但不能做DDL(比如alter table)操作。


    8.Bulk Update Locks

           主要在批量导数据时用(比如用类似于oracle中的imp/exp的bcp命令)。不难理解,程序员往往也不需要关心,不赘述了。

  • 相关阅读:
    Java操作excel
    (13)C++ 多态
    (12)C++ 继承
    (18)C++ string和标准模板库
    parseInt(str),parseFloat(str)
    JavaScript substring() 方法
    JavaScript遍历对象中所有元素
    JavaScript中的number跟string
    mybatis动态sql
    Android数据存储之Android 6.0运行时权限下文件存储的思考
  • 原文地址:https://www.cnblogs.com/Li-yuan/p/6650616.html
Copyright © 2011-2022 走看看