在之前的一片随笔中,简单的说了一下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. Sublime Text 2/3安装使用及常用插件

    一.介绍 Sublime Text 是一款较新的编辑器,它轻量.简洁.高效,良好的扩展性以及跨平台等特性,使得越来越多的开发人员喜爱.它是一款收费的商业软件,但可以免费无限制无限期的试用,只会偶尔提醒 ...

  2. 评论Final版本发布

    1.  新蜂:俄罗斯方块 产品方面:俄罗斯方块在Beta版本基础上新增了许多功能,其中游戏中按A键可以开启瞄准,这个功能在市面上是具有先发优势的,算是一个较大的亮点:在改进了文字ui和方块的贴图以及游 ...

  3. .NET DataSet、DataTable操作记录

    一直在习惯.net的编程思维,或是说C#吧.因为前几年一直在用PHP做站,现在用.net很不习惯,主要C#都依赖对控件.类的熟悉,不然很多功能都实现不了. 需求 最近做了一功能,从SQL Server ...

  4. 剖析JavaScript函数作用域与闭包

    在我们写代码写到一定阶段的时候,就会想深究一下js,javascript是一种弱类型的编程语言,而js中一个最为重要的概念就是执行环境,或者说作用域.作用域重要性体现在哪呢?首先,函数在执行时会创建作 ...

  5. C++快速入门系列教程

    C++ 60分钟入门教程:http://see.xidian.edu.cn/cpp/biancheng/view/2755.html

  6. shell 命令集

    shell 常用知识点--------------------------------------- sed 用法 http://www.cnblogs.com/edwardlost/archive/ ...

  7. W5500 keep-alive的用途与用法--新华龙电子

    大家是否遇到过这样的问题,W5500作为服务器已经建立连接,突然网线掉了,然后再去连接W5500,就连不上了.为什么?下面对这个问题进行解释说明,并提出解决办法. 图1中的上位机程序作为客户端,连接W ...

  8. JS定义函数的两种方式:函数声明和函数表达式

    函数声明 关于函数声明的方式,它的一个重要的特性就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明.这就意味着可以把函数声明放在调用它 ...

  9. RabbitMQ消息机制单人分发

    static void Main(string[] args) { // More.SendMessage(); var factory = new ConnectionFactory(); fact ...

  10. C#读写者线程(用AutoResetEvent实现同步)(转载)

    C#读写者线程(用AutoResetEvent实现同步) 1. AutoResetEvent简介 通知正在等待的线程已发生事件.无法继承此类. 常用方法简介: AutoResetEvent(bool ...