各位朋友上午好,很高兴能够有这个机会再次来到XXX,今天我准备就SQL SERVER的锁来给大家做个简单的介绍,计划分为以下五个部分来做讲解,1,2,3,4,5

下面我们先来看看第一部分:由锁阻止的并发性问题,锁在数据库中是一个非常重要的概念,他主要用于多用户环境下保证数据的完整性和一致性,如果数据库中没有锁的话,那么多个用户同时对数据库的并发操作时就会带来下面几种数据不一致的问题,

1.丢失更新: 概括一句话就是第二事务的更改覆盖了第一个事务的更改。

 例子:比如飞机订票系统,甲售票点(甲事务)读出某航班的机票余额A=10.  乙售票点(乙事务)读出同一航班的机票余额A,也为10; 甲售票点卖出一张机票,修改余额A←A-1.所以A为9,把A写回数据库;乙售票点也卖出一张机票,修改余额A←A-1=9,把A写回数据库.  结果明明卖出两张机票,数据库中机票余额只减少1张。

    解决:现在的SQL对这个问题已有了较好的控制,一般不会出现这个问题

2.脏读:可以概括为读到进行一半的事务.

     T2(乙)可以看到T1(甲)进行一半的事务,也就是看到新修改的数据25,但是某T1事务由于某种原因最后进行了回滚(Rollback Tran),所以该条记录最后没有真正更新到数据库里,所以也就会发生T2误将过程中的数据库当成查询结果

     解决:提升事务隔离级别到  Read Committed 已提交读,也是SQL SERVER 默认的设置;当你查询的资料的正确性不是那么重要,只是隔段时间查询下状态,这次查到错的下次再查对的,也没有太大的关系。

3.不可重复读:指在同一个事务中,两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。

   比如事务T1读取某一数据,事务T2读取并修改了该数据,当T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果,

   解决:提升隔离级别为 可重复读

   这样事务T2 在两次读取数据时,事务T1如果企图更改表T中的数据(细节到事务T2读取数据)时,就会被阻塞,直到事务T1提交!   这样就保证了,事务T2两次 读取的数据的一致性。

4.幻影读

   即使像上面隔离级别提升到可重复读  ,但是这仍然无法阻止别人做新增的动作,所以也就会导致第一次查询没有的资料,第二次查询却出现了,成为幻影读

   解决:提升隔离级别为序列化  此时SQL SERVER会对该事务所使用到的范围下RangeShare锁,例子中就是所有可以以‘A’开头的客户编号,提升等级后,其他人就不可以插入资料到这个范围内,从而来避免欢幻影读。

可以锁定的资源:

  在数据库里的各种对象非常多,下面我们就来看看锁所能够锁定的资源都有哪些?

  那么说到行锁,行锁是个什么概念呢,比如说一张有100W条记录的表,若是采用行锁的话,就可以有100W个进程同时访问读取,但是会很浪费资源,

页级锁的并发数较行锁来讲就稍少,资源占用也少;

锁粒度是被封锁目标的大小,封锁粒度小则并发性高,但开销大,封锁粒度大则并发性低但开销小,

SQL默认都是先锁定最底层的对象,如ROW 行,这样可以避免大范围的锁定使得其他人无法同时存取该范围内的其他数据,若内存不足时,SQL SERVER会自动提升锁的范围,以减少管理锁的负担。这个过程默认是由SQL SERVER自动完成的,它会在资源状况和并发数之间选择一个平衡点。

锁的类型

共享锁:

共享锁锁定的资源可以被其他用户读取,但其他用户无法修改它,在执行Select时,SQL Server会对对象加共享锁,并允许不同的事务同时读取相同的记录,

排它锁:

若是要对某比资料做INSERT,UPDATE,DELETE等操作,则需要先放排它锁,排它锁会在事务开始后,一直保留到事务结束。

更新锁,

   更新锁是在对同一个资源从开始的查询要转成更新时使用,就是先是共享锁变成更新锁,再进一步的变成排它锁,比如你像查一条记录,要更新它的内容的时候就是如此。更新锁与共享锁是兼容的,可以防止通常形式的死锁。

意向锁,

大容量更新锁

锁的兼容性:

   当记录上已有共享锁,其他人可以继续放共享锁,也就是我看资料时,你也可以看资料,但当资料已有共享锁时,不能再加排它锁,就是有人看资料时,别人不可以    同时修改资料。

   若资料上已有排它锁时候也不能加共享锁或排它锁,所以就是我在该资料时,你不可以看也不可以改.

    当用户要修改记录时,所加的排它锁几乎可以让任何其他的操作都不能执行,除了查询表的表结构(Sch-S), 表结构的查询除了在修改表结构时不可以查询,其他任何时候都可以

 Dead Lock:

指多个用户(进程)分别锁定了一个资源,并又试图请求锁定对方已经锁定的资源,这就产生了一个锁定请求环,导致多个用户(进程)都处于等待对方释放所锁定资源的状态.

   Microsoft SQL ServerDatabase Engine死锁监视器定期检查陷入死锁的任务。如果监视器检测到循环依赖关系,将选择其中一个任务作为牺牲品,然后终止其事务并抛出错误号:1205。

 

 

 

Read Uncommitted (未提交读)

Read Committed (已提交读)

Repeatable Read (可重复读)

Serializable (序列化)

posted on 2010-10-18 17:17  秋来九月八  阅读(243)  评论(0编辑  收藏  举报