在之前的一片随笔中,简单的说了一下SQL Server中的隔离级别。而SQL Server的隔离级别是通过锁的机制来实现的。现在深入一下,谈谈SQL Server中的锁。

开始之前,先要定义一下前提:

1.隔离级别的实现其实就是在不同的资源上加锁。
2.对数据库的每一次访问(CRUD)我们称其为一个事务(在begin tran,commit tran|rollback tran中的语句块,或者即席查询--单条SQL)。不同的事务如果同时访问同一个数据库资源,会产生一系列的问题(见
Sql Server隔离级别(1)
)。
3.大多数的事务在访问资源之前都会尝试对资源加上对应的锁(acquire lock,请求一个锁)。只有在Read Uncommitted隔离级别以及在表上加了WITH(No Lock) hint的Select语句不会请求锁。
3.读锁(共享锁S)不会阻塞读锁,读锁会阻塞写锁(独占锁X),写锁会阻塞读锁。
4.在一个事务中,只有在Repeatable Read或更高的隔离级别下,会将select语句的读锁一直保持到事务结束(提交或回滚),Read Committed隔离级别会造成不可重复读的原因就是在事务中的select语句执行完成后(事务没有执行完)读锁就直接释放了。

5.当前事务中的锁可以通过SELECT * FROM sys.dm_tran_locks 这个查询查看

====================================开始的分割线=========================================================

Server中存在不同粒度的锁:行锁,键锁,页锁,表锁等等,之所以要存在这些锁,是为了在并发性与系统开销间做一个平衡。粒度更小的锁将带了更好的并发性和更大的系统开销例如行锁的并发性好于表锁,不过系统的开销却大于表锁。

a.获取表锁时:整张表包括未被查询使用的行将会被锁住,其他试图请求表上不兼容锁的查询都将等待。此时系统中只需要维护一个表锁即可。

b.获取行锁时:只有查询使用到的行会被锁住,请求其他行的查询可以顺利的进行。此时并发性好于a,但是对于每一个被使用的行系统都要维护一个锁,系统开销增加。

一下是一些锁的资源,这里先大概了解下就好

资源

说明

RID

行标识,用于锁住整个表的其中一行

KEY

通过在索引来锁住行,用于在序列化的隔离级别中锁住一个行的范围。

PAGE

8kb大小的数据页或者索引页

EXTENT

一组连续的八页,例如数据页或索引页。

TABLE

包括所有数据和索引的整个表。

DATABASE

数据库。

在一个SQL执行的时候,或多或少都会请求上述的资源,而对这些资源的请求可以看成是对这些资源上的锁的请求。只有成功的请求到这些资源上的锁或者说成功的在当前的事务中对这些资源加锁,才能对这些资源进行CRUD的操作。

对于不同的资源请求,SQL Server会应用不同的锁模式来试图在资源上加锁。经常接触到的锁模式如下:

共享锁(S):
请求到共享锁(读锁)允许事务可以读取某一个资源,此时其他的事务将请求不到该资源的独占锁(写锁),但是可以请求到共享锁。在资源读取完成后,共享锁将会释放(即使此时事务还没有结束)。除非事务在read repeatable或者更高的隔离级别下执行,或者通过使用sql hint在事务执行时一直持有锁(例如WITH(HOLDLOCK)),共享锁将持续到事务结束。

更新锁(U):
更新锁的存在是为了避免在并发环境下不同事务的Update语句造成死锁。

一个典型的Update操作将经过以下两步:
步骤1.获取将要更新的资源的共享锁将数据读出
步骤2.将共享锁转换成独占锁并将更新的数据写入到资源中

考虑到并发环境,两个事务同时到达步骤1,获取到同一资源的共享锁(共享锁之间不会阻塞)。然后两个事务都开始将试图共享锁转换成独占锁,发现无法转换,因为此时两个事务同时还保留了对资源的共享锁,而共享锁是会阻塞独占锁的。两个事务都等待对方的共享锁释放,于是就产生了死锁。

上述的Update模式中,一个Update操作将不再是原子操作,因为在步骤1到步骤2之间会被其他的事务影响。所以需要引入更新锁来替换步骤1中获取的共享锁,更新锁是互斥的,所以将不会出现两个Update操作同时获取到更新锁的情况。只可能是一个事务获取到了更新锁,而另一个事务只好等待更新锁的释放。

在Update用更新锁来替代共享锁来查找资源将防止并发更新产生死锁,并且由于更新锁可以和共享锁兼容,所以其他的事务依然可以在资源上放置共享锁。

独占锁(X)
独占锁阻塞其他的所有锁,无法读取或者修改加了独占锁的资源。

意向锁(IS,IX,SIX)
一个意向锁表明Sql Server希望获取当前资源的层次更低的共享锁或者独占锁。例如,表上的IS锁(意向共享锁)表明事务将要表中的页或者行(粒度比表更小的资源)上放置共享锁,而放置意向锁将避免随后的其他事务在表上获取到独占锁。意向锁能够提高性能,因为当一个事务要获取一个表的锁的时候不用再去检查表的资资源(页或行)是否被锁住了, 而只需要检查表上是否有意向锁就行了。

SQL server 2005中的锁(1)的更多相关文章

  1. SQL Server 2005中的分区表

    记录笔记: 转自 猪八戒学做网站 SQL Server 2005中的分区表(一):什么是分区表?为什么要用分区表?如何创建分区表? SQL Server 2005中的分区表(二):如何添加.查询.修改 ...

  2. SQL Server 2005中更改sa的用户名和密码

    修改数据库SA账号名称的代码如下:  代码如下: Alter LOGIN sa DISABLE Alter LOGIN sa WITH NAME = [systemAccount] "sys ...

  3. SQL Server 2005 中实现通用的异步触发器架构

    在SQL Server 2005中,通过新增的Service Broker可以实现异步触发器的处理功能.本文提供一种使用Service Broker实现的通用异步触发器方法. 在本方法中,通过Serv ...

  4. SQL SERVER 2005中同义词实例

    From : http://www.cnblogs.com/jackyrong/archive/2006/11/15/561287.html 在SQL SERVER 2005中,终于出现了同义词了,大 ...

  5. SQL Server 2005中的分区表(六):将已分区表转换成普通表(转)

    我的俄罗斯名叫作“不折腾不舒服斯基”,所以,不将分区表好好折腾一下,我就是不舒服. 在前面,我们介绍过怎么样直接创建一个分区表,也介绍过怎么将一个普通表转换成一个分区表.那么,这两种方式创建的表有什么 ...

  6. 浅析SQL Server 2005中的主动式通知机制

    一.引言 在开发多人同时访问的Web应用程序(其实不只这类程序)时,开发人员往往会在缓存策略的设计上狠下功夫.这是因为,如果将这种环境下不常变更的数据临时存放在应用程序服务器或是用户机器上的话,可以避 ...

  7. SQL Server 2005中的CHECKSUM功能

    原文:SQL Server 2005中的CHECKSUM功能 转自此处 页面 checksum 是SQL2005的新功能,提供了一种比残缺页检测强大的机制检测IO方面的损坏.以下是详细描述: 页面 C ...

  8. SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)

    原文:[转]SQL SERVER 2005中如何获取日期(一个月的最后一日.上个月第一天.最后一天.一年的第一日等等) 在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天       ...

  9. SQL Server 2005中设置Reporting Services发布web报表的匿名访问

    原文:SQL Server 2005中设置Reporting Services发布web报表的匿名访问 一位朋友提出个问题:集成到SQL Server 2005中的Reporting Services ...

随机推荐

  1. Tomcat Connector三种运行模式(BIO, NIO, APR)的比较和优化

    Tomcat Connector的三种不同的运行模式性能相差很大,有人测试过的结果如下: 这三种模式的不同之处如下: BIO: 一个线程处理一个请求.缺点:并发量高时,线程数较多,浪费资源. Tomc ...

  2. 如何在Delphi里面查看程序的汇编代码?

    开发工具:Delphi 10 Update2 1,在源代码中设置至少一个断点,目的让我们进入调试模式. 2,启动调试,当程序进入调试模式,停留在我们设定的断点处时候,使用快捷键"CTRL+A ...

  3. TensorFlow中权重的随机初始化

    一开始没看懂stddev是什么参数,找了一下,在tensorflow/python/ops里有random_ops,其中是这么写的: def random_normal(shape, mean=0.0 ...

  4. interview que

    百度: MySQL InnoDB存储的文件结构 索引树是如何维护的? 数据库自增主键可能的问题 Redis的并发竞争问题如何解决了解Redis事务的CAS操作吗 分析线程池的实现原理和线程的调度过程 ...

  5. .this语句指的是什么

    This通常指的是当前对象的引用

  6. Java面向对象㈡ -- 继承与多态

    Java的继承是通过extends和implement来实现的,Java不支持多继承,但是Java支持多层继承以及多实现(接口).Java继承有一个关键字super是用来指向父类.Java继承衍生出覆 ...

  7. Python-5 数据类型、操作符

    #1 数值类型: 整型int.浮点型float(科学记数法 e 或 E).布尔型bool #2 字符串: 与整型.浮点型转化:int()--截断处理 float() str() #3 获取数据类型: ...

  8. Linq并行执行

    一.     并行LINQ 1.  并行查询 .NET4在System.Linq名称空间中包含一个新类ParalleIEnumerable ,可以分解查询的工作使其分布在多个线程上.尽管Enmerab ...

  9. JS-获取URL请求参数

    前言:原来做过一个项目,需要实现一个页面打印的功能,由于项目中使用了AngularJS+Bootstrap等前端框架,需要打印的页面又在弹出框中,使用了Bootstrap的模态框后发现打印的效果不太好 ...

  10. 1、基于MFC的OpenGL程序

    首先,使用的库是GLUT以及GLAUX,先下载两者,添加查找路径以及链接   一.单文本文件   工程openGLMFC 1.创建单文本文件   2.添加路径.链接 方法如之前篇章所示, 链接库为op ...