深入理解sqlserver2008的锁机制

上传人:xiao****1972 文档编号:84814459 上传时间:2019-03-04 格式:DOCX 页数:23 大小:501.81KB
返回 下载 相关 举报
深入理解sqlserver2008的锁机制_第1页
第1页 / 共23页
深入理解sqlserver2008的锁机制_第2页
第2页 / 共23页
深入理解sqlserver2008的锁机制_第3页
第3页 / 共23页
深入理解sqlserver2008的锁机制_第4页
第4页 / 共23页
深入理解sqlserver2008的锁机制_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《深入理解sqlserver2008的锁机制》由会员分享,可在线阅读,更多相关《深入理解sqlserver2008的锁机制(23页珍藏版)》请在金锄头文库上搜索。

1、相比于 SQL Server 2005(比如快照隔离和改进的锁与死锁监视),SQL Server 2008 并没有在锁的行为和特性上做出任何重大改变。SQL Server 2008 引入的一个主要新特性是在表级控制锁升级行为的能力。新的LOCK_ESCALATION表选项允许你启用或禁用表级锁升级。这个新特性能够减少锁竞争并且改善并发性,特别是对于分区表(partitioned tables)。SQL Server 2008 的另一个改变是不再支持Locks configuration设定。同样不再被支持的还有timestamp数据类型,它已被rowversion数据类型取代。为什么需要锁?

2、在任何多用户的数据库中,必须有一套用于数据修改的一致的规则。对于真正的事务处理型数据库,当两个不同的进程试图同时修改同一份数据时,数据库管理系统(DBMS)负责解决它们之间潜在的冲突。任何关系数据库必须支持事务的ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、永久性(Durability)。ACID属性确保数据库中的数据更改被正确地收集到一起,并且数据将保持在与所采取动作相一致的状态。锁的主要作用是提供事务所需的隔离。隔离确保事务之间不会相互干扰,即,一个给定的事务不会读取或修改正在被另一个事务修改的数据。此外,锁提供的隔离性有助于

3、保证事务间的一致性。没有锁,一致的事务处理是不可能的。SQL Server 中的事务隔离级别 隔离级别决定了一个事务中正被访问或修改的数据受保护并免于被他事务修改的程度。理论上,每个事务都应该完全与其他事务隔离开来。然而,出于可行性和性能方面的原因,实践中这几乎是不可能做到的。在并发环境中如果没有锁和隔离,可能发生以下4种情况: 丢失更新 - 在这种情况下,事务与事务之间没有隔离。多个事务能够读取同一份数据并且修改它。最后对数据集做出修改的事务将胜出,而其他所有事务所作的修改都丢失了。 脏读 - 在这种情况下,一个事务能够读取正被其他事务修改的数据。被第一个事务读取的数据是不一致的,因为另一个

4、事务可能会回滚所作的修改。 不可重复读 - 这种情况有点类似于没有任何隔离,一个事务两次读取数据,但是在第二次读取发生前,另一个事务修改了该数据;因此,两次读取所得到的结果是不同的。因为读操作不能保证每次都是课重复进行的,这种情况被称作“不可重复读”。 幻读 - 这种情况类似于不可重复读。然而,不是先前被读取的实际行在事务完成前发生了改变,而是额外的行被添加到了表中,导致第二次读取返回了不同的行集合。 SQL Server 2008 支持6种隔离级别,分别是 Read Uncommitted Read Committed Repeatable Read Serializable Snapsho

5、t Read Committed Snapshot (详情请参考我的另一篇blog:SQL Server 2008 R2 事务与隔离级别实例讲解)锁管理器 解决不同用户进程间锁冲突的职责落到了SQL Server Lock Manager身上。SQL Server 自动地给进程分配锁,以保证资源的当前用户拥有该资源的一致视图,从某个特定操作的开始至结束。Lock Manager 负责决定适当的锁类型(如shared, exclusive, update)和锁粒度(如row, page,table),根据正在执行的操作类型和所影响的数据量。Lock Manager还管理试图访问同一资源的锁类型之

6、间的兼容性,解决死锁,必要时升级锁到一个更高的级别。Lock Manager 为共享数据和内部系统资源管理锁。对于共享数据,Lock Manager 管理表以及数据页、文本页、叶级索引页上的行级锁、页级锁和表级锁。内部地,Lock Manager使用门闩(latch)来管理索引行和页上的锁控制对内部数据结构的访问,以及在某些情况下,用于取回单个的数据行。门闩提供了更好的系统性能,因为它不像锁那般资源密集。门闩也提供了比锁更好的并发性。门闩典型地用于像页拆分、索引行的删除、索引中行的移动等操作。锁与门闩之间最主要的区别在于,锁在整个事务存续期间都被持有,而门闩仅在需要它的操作存续期间被持有。锁用

7、于保证数据的逻辑一致性,而门闩用于保证数据和数据结构的物理一致性。SQL Server 锁类型 锁在SQL Server中是自动处理的。Lock Manager 基于事务类型(如SELECT, INSERT, UPDATE, 或者DELETE)选择锁的类型.Lock Manager使用以下的锁类型: 共享锁 更新锁 独占锁 意向锁 架构锁 大容量更新锁 除了选择锁类型,Lock Manager还基于所执行语句的性质以及所影响的行数自动地调整锁粒度(如row, page, table)。共享锁 缺省地,SQL Server 为所有读操作应用共享锁。顾名思义,共享锁不是独占的。理论上,在任何时刻,

8、一个资源上可以持有无限数量的共享锁。此外,默认情况下,一个进程仅仅当资源正被读取期间才会锁定该资源,这时也只有唯一的共享锁存在。比如SELECT * from authors,当查询开始时,先锁定authors表中的第一行;当第一行被读取以后,它上面的锁被释放,并且了第二行上的锁;第二行读到以后,它上面的锁被释放,同时获取了第三行上的锁;以此类推。按此方式,一个SELECT查询允许在读操作期间修改那些没有正在被读取的数据行。这增强了数据访问的并发性。共享锁不仅与其他共享锁兼容,也与更新锁兼容。共享锁不会阻止其他进程在一个给定的行或页上获取额外的共享锁或更新锁。任何时候事务多个事务或进程可以持有

9、多个共享锁,这些事务不会影响数据的一致性。然而,共享锁确实会阻止独占锁的获取。当行或页上持有共享锁的时候,任何试图修改其数据的事务将被阻塞,直到 所有的共享锁被释放。更新锁 更新锁用于锁定用户进程想要修改的行或页。当一个事务试图修改某行时,它必须先读取该行以确保它正在修改合适的记录。假如事务先在资源上加了共享锁,要修改该记录,最终它将需要获取该资源上的独占锁,以防止任何其他事务修改同一记录。问题是,当多个事务试图同时修改同一资源的时候这可能导致死锁。如图所示。SQL Server中的更新锁就是用来防止此类死锁场景的。更新锁是部分独占的,就是说在任何时候任何资源上只能获取唯一的更新锁。然而,更新

10、锁兼容于共享锁,即它们可以同时被同一资所获取。事实上,更新锁意味着一个进程想要修改某记录,并且将也想修改该记录的其他进程排除在外。然而,更新锁允许其他进程获取共享锁以便读取数据,直到UPDATE或DELETE语句完成被影响记录的定位。之后,进程尝试将每一个更新锁升级为独占锁。这时候,进程等待该记录上当前被持有的所有共享锁释放。当共享锁全部释放以后,共享锁就被升级为独占锁。接着执行数据修改,独占锁在事务的余下时间内一直被持有。独占锁 如前所述,当事务准备好要修改数据时,独占锁被分配给它。资源上的独占锁确保没有其他任何事务能妨碍被持有独占锁的事务锁定的数据。SQL Server在事务结束时释放独占

11、锁。独占锁与其他的所类型不兼容。如果资源持有了独占锁,那么任何其他进程对该资源的读取或修改请求都将强制等待直到独占锁释放为止。同样地,如果其他进程当前持有该资源的读取锁(共享锁或更新锁),独占锁请求也被强制排队等待直到资源变得可用为止。意向锁 意向锁并不正真的构成一种锁定方式,而是充当一种机制,用以在较高的粒度级别上指示在较低(粒度)级别上所持有的锁类型。有3种类型的意向锁(分别对应于之前提到的3种锁类型):共享意向锁、独占意向锁、更新意向锁。举个例子来说,某进程持有的表级共享意向锁意味着,该进程当前在该表的行或页级持有共享锁。意向锁的存在防止其他事务获取与现存的行或页级锁不兼容的表级锁的企图

12、。意向锁提升了SQL Server锁的性能。它允许在表级别检查锁来决定在该表的行或页级持有的锁类型,而不是在表中的行或页级查遍多个锁。当监视锁活动时典型地你将看到3种类型的意向锁:意向共享锁(IS)、意向独占锁(IX)、意向独占共享锁(SIX)。IS锁表明,在低级别资源(行或页)上,进程当前持有或有意图持有共享锁。IX锁表明,在低级别资源上,进程当前持有或有意图持有独占锁。SIX锁出现在特殊情况下,当一个事务在资源上持有共享锁,后来又需要意向独占锁(IX),这时候,S锁被转换成SIX锁。架构锁 SQL Server 使用架构锁来保持表结构的完整性。不像其他提供数据隔离的锁类型,架构锁提供事务中

13、对数据库对象如表、视图、索引的schema隔离。Lock Manager提供2种类型的架构锁:架构稳定性锁(Sch-S)- 当事务引用了索引或数据页时,SQL Server在对象上加Sch-S锁。这确保当其他进程仍然引用着该对象时,没有其他事务能够修改该对象的Schema,如删除索引或删除、修改存储过程或表。架构修改锁(Sch-M) - 当一个进程需要修改某对象的结构(如修改表,重编译存储过程)时, Lock Manager在对象上加Sch-M锁。在锁存在期间,没有其他任何事务能够引用该对象,直到(对象结构的)修改完成并提交为止。大容量更新锁(BU) 大容量更新锁是一种特殊类型的锁,仅用于使用

14、bcp实用程序或者BULK INSERT命令向表中大容量复制数据时。仅仅当给bcp或BULK INSERT命令指定了TABLOCK提示,或者使用 sp_tableoption 设置了 table lock on bulk load 表选项时,BU锁才能用于大容量数据复制操作。大容量更新 (BU) 锁允许多个 bulk copy 进程将数据并发地大容量复制到同一表,同时防止其它不进行大容量复制数据的进程访问该表。如果有任何其他进程在该表上持有锁,则不能给该表施加BU锁。SQL Server 锁粒度 所谓所粒度,从本质上说就是,为了给事务提供完全的隔离和序列化,作为查询或更新的一部分被锁定的数据的

15、总量(的大小)。Lock Manager需要在资源的并发访问与维护大量低级别锁的管理开销之间取得平衡。比如,锁的粒度越小,能够同时访问同一张表的并发用户的数量就越大,不过维护这些锁的管理开销也越大。锁的粒度越大,管理锁需要的开销就越少,而并发性也降低了。下图说明了锁的大小与并发性之间的权衡取舍。当前,SQL Server通过在行或更高级别加锁来平衡性能和并发性。基于各种因素,如key的分布,行的数量,行的密度,查询参数(SARGs)等等,Query Optimizer内部地做出锁粒度选择,程序员不需要为此担心。SQL Server提供了大量T_SQL扩展,使你能从锁的角度来更好地控制查询行为。SQL Server 提供以下的锁级别: DATABASE - 无论何时当一个SQL Server 进程正在使用除master以外的数据库时,Lock Manager为该进程授予数据库级的锁。数据库级的锁总是共享锁,用于跟踪何时数据库在使用中,以防其他进程删除该数据库,将数据库置为脱机,或者恢复数据库。注意,由于master和tempdb数据库不能被删除或置为脱机,所以不需要在它们之上加锁。 FILE - 文件级的锁用于锁定数据库文件。 EXTENT - Extent锁用于锁定extents,通常仅在空间分配和重新分配的时候使用。一个extent由8个连续的数据页或索引页组成。Ext

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号