用索引降低锁并发性
我们为什么要讨论锁机制?如果用户操作数据时尽可能锁定最少的数据,这样处理过程
就不会等待被锁住的数据解锁,从而可以潜在地提高SQL Server的性能。如果有2 0 0个用户打
算修改不同顾客的数据,仅对存储单个顾客信息的单一行进行加锁要比锁住整个表好得多。
那么,用户如何只锁定行而不是表呢?当然是使用索引了。正如前面所提到的,对存有
要修改数据的字段使用索引可以提高性能,因为索引能直接找到数据所在的页面,而不是搜
索所有的数据页面去找到所需的行。如果用户直接找到表中对应的行并进行更新操作,只需
锁定该行即可,而不是锁定多个页面或者整个表。
性能的提高不仅仅是因为在修改时读取的页面较少,而且锁定较少的页面潜在地避免了
一个用户在修改数据完成之前其他用户一直等待解锁的情况。
务范围、事务隔离等级和锁机制
事务中遵循的锁定规则取决于系统正在使用的事务隔离等级的类型。表3 - 4描述了它们的
差别。
表3-4 事务隔离等级与锁定
隔离等级
锁的类型和长度
共享独占
读不交付所需长度事务的长度
读交付所需长度事务的长度
可重复读事务的长度事务的长度
如表中所示,共享锁只有在真正检索数据时才锁定数据,一旦操作完成立即释放锁,而
不管事务是否完成。这正是出现“重影现象”的原因。如果事务隔离等级设置为可重复读(或
可串行化),共享锁在事务全过程中都处于保持状态。独占锁则在事务全过程中都处于保持状
态而不考虑隔离等级。
这将意味着什么呢?它是指事务必须持续足够长来维持数据完整性。冗长的修改数据事
务(即,使用独占锁)会使其他事务等待该事务的完成,从而降低SQL Server的性能。包含数据
修改操作语句的事务执行时间越长,锁机制并发的潜力就越大。
中所列的脚本实例在a u t h o r s表上持有一个共享锁,它将用户检查服务器当
前活动的时间推迟两分钟。
测试事务隔离等级
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
G O
BEGIN TRAN
SELECT *
FROM authors
WHERE au_lname = 'Green'
WAITFOR DELAY '00:02:00'
ROLLBACK TRAN
GO
可锁定的资源及其描述
资源类型描述
R I D R I D即行标识,用于锁定表中的单行。允许更新,插入和删除没有锁定的行
K e y 键锁是索引中的行锁
P a g e 页面锁锁定表或索引中全部8 K B页面,包括该页面上的所有行
E x t e n t 范围锁锁定一组相邻的几个页面,与页面锁相比,它锁定在一个范围内所有页
面中的所有行
Ta b l e 表锁锁定整个表,包括表中的所有数据和索引
D B D B锁即数据库锁,锁定整个数据库和数据库中的所有表
锁模式及其描述
锁模式描述
共享共享( S h a r e d )锁用于不修改数据的操作,如S E L E C T语句。当数据读操作完成时
就释放锁。多个用户可以在同一对象上获得共享锁,但任何用户都不能在已存在
共享锁的对象上获得更新锁或者独占锁
更新更新( U p d a t e )锁用于U P D AT E操作,它用来打破在执行更新操作时发生的死锁。
执行U P D AT E操作时, SQL Server首先使用共享锁读记录,而后使用独占锁修改
该记录。如果有两个用户试图更新同一记录,则他们在同一记录上请求共享锁,
并都试图将自己的锁修改为独占锁。因为每个用户都等待对方释放锁,他们又都
持有共享锁,因此就会出现锁等待的情况。SQL Server会检测到锁等待,并且撤
销引起死锁的事务中的一个;这样只有一个用户可以在该对象上获得更新锁。当
真正实际进行数据修改时,锁会升级为独占锁
独占独占( E x c l u s i v e )锁在数据执行修改操作时使用,例如I N S E RT,U P D AT E和
D E L E T E。该类型的锁保证其他用户不能访问已锁定的对象
意向共享意向( I n t e n t )共享锁是指事务试图锁定低层资源的一部分而非全部。例如,如果
表中的大多数行都要进行该操作,事务就可以使用意向共享锁锁定表
意向独占意向独占锁用来指示事务对低层资源的一部分而非全部进行修改
意向独占共享该类型的锁用来指示事务读出全部低层资源,而后使用意向独占锁对其中的一
部分资源进行修改
模式有两种模式( S c h e m a )锁可以使用,当用户执行任何类型的数据定义语言,如加
入一列或删除表时,一般使用模式修改( m o d i f i c a t i o n )锁;当SQL Server正在编译
一个查询并且要阻止发生模式修改情况时,使用模式固定( s t a b i l i t y )锁
块更新当SQL Server将数据块拷贝到表中时,使用块更新(bulk update)锁。当多个处
理过程持有块更新锁时,就可以将数据块拷贝到表中,同时阻止那些没有进行数
据拷贝的用户访问这些数据