暂无图片
暂无图片
暂无图片
暂无图片
暂无图片
深入理解 SQL Server 2008 的锁机制_ITPUB博客.pdf
31
15页
4次
2024-12-12
免费下载
深入理解 SQL Server 2008 的锁机制_ITPUB博客
深入理解 SQL Server 2008 的锁机制
原创 SQL Server 作者:yuzhangqi 时间:2014-02-26 14:25:37 24700 1
相比于 SQL Server 2005(比如快照隔离和改进的锁与死锁监视),SQL Server 2008 并没有在锁的行为和特
性上做出任何重大改变。SQL Server 2008 引入的一个主要新特性是在表级控制锁升级行为的能力。新的
LOCK_ESCALATION表选项允许你启用或禁用表级锁升级。这个新特性能够减少锁竞争并且改善并发性,特别
是对于分区表(partitioned tables)。
SQL Server 2008 的另一个改变是不再支持Locks configuration设定。同样不再被支持的还有timestamp数据
类型,它已被rowversion数据类型取代。
为什么需要锁?
在任何多用户的数据库中,必须有一套用于数据修改的一致的规则。对于真正的事务处理型数据库,当两个不
同的进程试图同时修改同一份数据时,数据库管理系统(DBMS)负责解决它们之间潜在的冲突。
任何关系数据库必须支持事务的ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性
(Isolation)、永久性(Durability)。ACID属性确保数据库中的数据更改被正确地收集到一起,并且数据将
保持在与所采取动作相一致的状态。
锁的主要作用是提供事务所需的隔离。隔离确保事务之间不会相互干扰,即,一个给定的事务不会读取或修改
正在被另一个事务修改的数据。此外,锁提供的隔离性有助于保证事务间的一致性。没有锁,一致的事务处理
是不可能的。
SQL Server 中的事务隔离级别
隔离级别决定了一个事务中正被访问或修改的数据受保护并免于被他事务修改的程度。理论上,每个事务都应
该完全与其他事务隔离开来。然而,出于可行性和性能方面的原因,实践中这几乎是不可能做到的。在并发环
境中如果没有锁和隔离,可能发生以下4种情况:
丢失更新 -- 在这种情况下,事务与事务之间没有隔离。多个事务能够读取同一份数据并且修改它。最后
对数据集做出修改的事务将胜出,而其他所有事务所作的修改都丢失了。
脏读 -- 在这种情况下,一个事务能够读取正被其他事务修改的数据。被第一个事务读取的数据是不一致
的,因为另一个事务可能会回滚所作的修改。
不可重复读 -- 这种情况有点类似于没有任何隔离,一个事务两次读取数据,但是在第二次读取发生前,
另一个事务修改了该数据;因此,两次读取所得到的结果是不同的。因为读操作不能保证每次都是课重复
进行的,这种情况被称作“不可重复读”。
幻读 -- 这种情况类似于不可重复读。然而,不是先前被读取的实际行在事务完成前发生了改变,而是额
外的行被添加到了表中,导致第二次读取返回了不同的行集合。
SQL Server 2008 支持6种隔离级别,分别是
Read Uncommitted
Read Committed
Repeatable Read
Serializable
Snapshot
Read Committed Snapshot
(详情请参考我的另一篇blog:SQL Server 2008 R2 事务与隔离级别实例讲解
锁管理器
解决不同用户进程间锁冲突的职责落到了SQL Server Lock Manager身上。SQL Server 自动地给进程分配锁,
以保证资源的当前用户拥有该资源的一致视图,从某个特定操作的开始至结束。
Lock Manager 负责决定适当的锁类型(如shared, exclusive, update)和锁粒度(如row, page,table),根
据正在执行的操作类型和所影响的数据量。
Lock Manager还管理试图访问同一资源的锁类型之间的兼容性,解决死锁,必要时升级锁到一个更高的级别。
Lock Manager 为共享数据和内部系统资源管理锁。对于共享数据,Lock Manager 管理表以及数据页、文本
页、叶级索引页上的行级锁、页级锁和表级锁。内部地,Lock Manager使用门闩(latch)来管理索引行和页
上的锁控制对内部数据结构的访问,以及在某些情况下,用于取回单个的数据行。门闩提供了更好的系统性
能,因为它不像锁那般资源密集。门闩也提供了比锁更好的并发性。门闩典型地用于像页拆分、索引行的删
除、索引中行的移动等操作。锁与门闩之间最主要的区别在于,锁在整个事务存续期间都被持有,而门闩仅在
需要它的操作存续期间被持有。锁用于保证数据的逻辑一致性,而门闩用于保证数据和数据结构的物理一致
性。
SQL Server 锁类型
锁在SQL Server中是自动处理的。Lock Manager 基于事务类型(如SELECT, INSERT, UPDATE, 或者DELETE)
选择锁的类型.Lock Manager使用以下的锁类型:
共享锁
更新锁
独占锁
意向锁
架构锁
大容量更新锁
除了选择锁类型,Lock Manager还基于所执行语句的性质以及所影响的行数自动地调整锁粒度(如row, page,
table)。
共享锁
缺省地,SQL Server 为所有读操作应用共享锁。顾名思义,共享锁不是独占的。理论上,在任何时刻,一个资
源上可以持有无限数量的共享锁。此外,默认情况下,一个进程仅仅当资源正被读取期间才会锁定该资源,这
时也只有唯一的共享锁存在。比如SELECT * from authors,当查询开始时,先锁定authors表中的第一行;当
第一行被读取以后,它上面的锁被释放,并且了第二行上的锁;第二行读到以后,它上面的锁被释放,同时获
取了第三行上的锁;以此类推。按此方式,一个SELECT查询允许在读操作期间修改那些没有正在被读取的数据
行。这增强了数据访问的并发性。
共享锁不仅与其他共享锁兼容,也与更新锁兼容。共享锁不会阻止其他进程在一个给定的行或页上获取额外的
共享锁或更新锁。任何时候事务多个事务或进程可以持有多个共享锁,这些事务不会影响数据的一致性。然
而,共享锁确实会阻止独占锁的获取。当行或页上持有共享锁的时候,任何试图修改其数据的事务将被阻塞,
直到 所有的共享锁被释放。
更新锁
更新锁用于锁定用户进程想要修改的行或页。当一个事务试图修改某行时,它必须先读取该行以确保它正在修
改合适的记录。假如事务先在资源上加了共享锁,要修改该记录,最终它将需要获取该资源上的独占锁,以防
止任何其他事务修改同一记录。问题是,当多个事务试图同时修改同一资源的时候这可能导致死锁。如图所
示。
SQL Server中的更新锁就是用来防止此类死锁场景的。更新锁是部分独占的,就是说在任何时候任何资源上只
能获取唯一的更新锁。然而,更新锁兼容于共享锁,即它们可以同时被同一资所获取。事实上,更新锁意味着
一个进程想要修改某记录,并且将也想修改该记录的其他进程排除在外。然而,更新锁允许其他进程获取共享
锁以便读取数据,直到UPDATE或DELETE语句完成被影响记录的定位。之后,进程尝试将每一个更新锁升级为
独占锁。这时候,进程等待该记录上当前被持有的所有共享锁释放。当共享锁全部释放以后,共享锁就被升级
为独占锁。接着执行数据修改,独占锁在事务的余下时间内一直被持有。
独占锁
of 15
免费下载
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文档的来源(墨天轮),文档链接,文档作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。