Understanding Locking in SQL Server——理解SQL Server中的锁

时间:2021-10-11 23:42:44

译者注:原文中用到了一个词:granularity。*上这样解释:It is the extent to which a larger entity is subdivided. 就是说,这个词表达了一个大的整体,比如一个系统,被分割成很多小部分时所用的尺度大小,更形象地说就是尺子的级别。比如,100块钱,按元这个这个尺度级别分,可以分100份儿;按照角这个尺度级别分,就可以分成100份儿。故,在本篇译文中,我们把这个词翻译为“级别”。

Microsoft® SQL Server™ 2000 引入了多级锁,可以实现在一个事务中给不同类型的资源加锁。为了尽量减少加锁操作的开销,SQL Server会自动选择给与执行任务级别相符的资源加锁。如果按照一个小的级别加锁,比如锁行,可以提高并发性能。但是也会导致同时锁住很多行时,系统负载的增大。如果按照一个大的级别来加锁,比如锁表,可以减少系统维护锁而产生的开销,但是由于锁住了整个表,其他事务无法获取这个表中的任何数据,从而增加维护并发请求而产生的负载。

SQL Server可以按照下表中的资源级别加锁。(按照级别升序排列)

Resource(资源) Description(描述)
RID Row identifier. Used to lock a single row within a table. 行标识。当为单行数据加锁时使用。
Key Row lock within an index. Used to protect key ranges in serializable transactions. 
索引中的行。用于在连续的事务中保护键值的排列。
Page 8 kilobyte –(KB) data page or index page. 页——8KB大小,SQL Server存储的基础数据结构。数据页,或者索引页。
Extent Contiguous group of eight data pages or index pages. 区,连续8个页称为一个区。
Table Entire table, including all data and indexes. 表,包括数据和索引。
DB Database. 数据库。

SQL Server 针对不同类型的资源,选择不同级别的锁。锁的级别不同,决定了事务并发时怎样获取到这些资源。

SQL Server 有下面几种级别的锁。

Lock mode(锁级) Description(描述)
Shared (S) 共享锁 Used for operations that do not change or update data (read-only operations), such as a SELECT statement.
用于不更改或更新数据(只读操作)时使用,比如SELECT语句。
Update (U) 更新锁 Used on resources that can be updated. Prevents a common form of deadlock that occurs when multiple sessions are reading, locking, and potentially updating resources later.
用于可能被更新的资源。避免一种常见的死锁发生:当多个会话同时执行读取、加锁操作,之后可能更新数据的情况。(因为此时多个会话同时拥有共享锁,并且都在等待其他会话放弃共享锁,然后自己升级为排他锁,故而产生死锁)
Exclusive (X) 排他锁 Used for data-modification operations, such as INSERT, UPDATE, or DELETE. Ensures that multiple updates cannot be made to the same resource at the same time.
用于数据修改操作,比如INSERT, UPDATE, 或者 DELETE。确保多个更新操作不会在同一时间操作于同一资源。
Intent 意图锁

Used to establish a lock hierarchy. The types of intent locks are: intent shared (IS), intent exclusive (IX), and shared with intent exclusive (SIX).

用于需要建立层级锁的场景。意图锁的类别有:共享意图锁,排他意图锁,共享排他意图锁。

Schema Used when an operation dependent on the schema of a table is executing. The types of schema locks are: schema modification (Sch-M) and schema stability (Sch-S).
Bulk Update (BU) Used when bulk-copying data into a table and the TABLOCK hint is specified.

共享锁

共享锁允许并发事务同时读取(SELECT)一个资源。一个资源加上共享锁之后,其他事务不能修改该资源的数据。如果事务的隔离级别没有被设置为repeatable read 或者更高,也没有锁hint语句指示要在事务运行期间保留共享锁,那么数据被读取之后,共享锁会被立即解除。

更新锁

更新锁可以避免一种常见的死锁。一个典型的更新语句包括加共享锁,读取记录,然后修改记录。而修改数据是需要加排他锁的。那么当两个事务同时对一个资源加了共享锁,并且尝试更新数据的时候,其中一个事务会尝试将共享锁转换为排他锁。但是这个转换必须等待另一个事务将共享锁释放,因为排他锁不能和共享锁共存。同样,另一个事务读物完数据,尝试更新时也会产生同样的等待。这样,一个死锁就形成了。

为了避免潜在的死锁问题,引入了更新锁。同一时间只能有一个更新锁加在同一资源上。如果一个事务修改这个资源,更新锁会被转换为排他锁。否则,更新锁会被转换为共享锁。

排他锁

排他锁,顾名思义,禁止并发的其他事务读取或者修改被加锁的资源。

意图锁

意图锁的使用表示SQL Server想要对粒度更小的资源拥有共享锁或者排他锁。比如,一个加在table上的共享意图锁意味着事务想要对这个表的页或者行拥有共享锁。设置表共享意图锁可以防止之后的事务对之前加共享锁的页所在的表拥有排他锁。意图锁之所可以提高性能,是因为SQL Server只在表这一层检查意图锁来决定事务是否可以安全滴给这个表加锁。这就避免了必须去检查表的每一行或者每一个页来决定是否可以给表加锁。

Intent locks include intent shared (IS), intent exclusive (IX), and shared with intent exclusive (SIX).

Lock mode Description
Intent shared (IS) Indicates the intention of a transaction to read some (but not all) resources lower in the hierarchy by placing S locks on those individual resources.
Intent exclusive (IX) Indicates the intention of a transaction to modify some (but not all) resources lower in the hierarchy by placing X locks on those individual resources. IX is a superset of IS.
Shared with intent exclusive (SIX) Indicates the intention of the transaction to read all of the resources lower in the hierarchy and modify some (but not all) resources lower in the hierarchy by placing IX locks on those individual resources. Concurrent IS locks at the top-level resource are allowed. For example, an SIX lock on a table places an SIX lock on the table (allowing concurrent IS locks), and IX locks on the pages being modified (and X locks on the modified rows). There can be only one SIX lock per resource at one time, preventing updates to the resource made by other transactions, although other transactions can read resources lower in the hierarchy by obtaining IS locks at the table level.

结构锁

Sch-M锁在数据库对象,比如表,结构改变时被使用。

Schema modification (Sch-M) locks are used when a table data definition language (DDL) operation (such as adding a column or dropping a table) is being performed.

Sch-S锁在查询被编译时使用。Sch-S锁不和事务中的其他锁冲突,包括排他锁。因此,即使一个事务拥有对资源的排他锁,另外的事务也可已继续执行语句编译。但是,DDL语句不能作用于表上。

Schema stability (Sch-S) locks are used when compiling queries. Schema stability (Sch-S) locks do not block any transactional locks, including exclusive (X) locks. Therefore, other transactions can continue to run while a query is being compiled, including transactions with exclusive (X) locks on a table. However, DDL operations cannot be performed on the table.

Bulk update (BU) locks are used when bulk copying data into a table and either the TABLOCK hint is specified or the table lock on bulk load table option is set using sp_tableoption. Bulk update (BU) locks allow processes to bulk copy data concurrently into the same table while preventing other processes that are not bulk copying data from accessing the table.

引用自: http://msdn.microsoft.com/en-us/library/aa213039(v=SQL.80).aspx