数据库引擎中的锁定
锁定是 MicrosoftSQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制。
在事务获取数据块当前状态的依赖关系(比如通过读取或修改数据)之前,它必须保护自己不受其他事务对同一数据进行修改的影响。 事务通过请求锁定数据块来达到此目的。 锁有多种模式,如共享或独占。 锁模式定义了事务对数据所拥有的依赖关系级别。 如果某个事务已获得特定数据的锁,则其他事务不能获得会与该锁模式发生冲突的锁。 如果事务请求的锁模式与已授予同一数据的锁发生冲突,则数据库引擎实例将暂停事务请求直到第一个锁释放。
当事务修改某个数据块时,它将持有保护所做修改的锁直到事务结束。 事务持有(所获取的用来保护读取操作的)锁的时间长度,取决于事务隔离级别设置。 一个事务持有的所有锁都在事务完成(无论是提交还是回滚)时释放。
应用程序一般不直接请求锁。 锁由数据库引擎的一个部件(称为“锁管理器”)在内部管理。 当数据库引擎实例处理 Transact-SQL 语句时,数据库引擎查询处理器会决定将要访问哪些资源。 查询处理器根据访问类型和事务隔离级别设置来确定保护每一资源所需的锁的类型。 然后,查询处理器将向锁管理器请求适当的锁。 如果与其他事务所持有的锁不会发生冲突,锁管理器将授予该锁。
下表列出的主题介绍了锁定的主要概念。
主题 |
说明 |
---|---|
可以请求各种类型的资源(例如,行、页、索引、表或数据库)的锁。 某些操作需要在多个粒度级别放置锁,以形成锁的层次结构。 |
|
锁有多种模式,这些模式指定其他事务对锁定资源所具有的访问级别。 |
|
如果多个事务的锁模式兼容,则这些事务可以获得对同一资源的并发锁。 如果某事务请求的锁模式与现有锁冲突,将暂停该事务直到第一个锁被释放。 |
|
锁定某个范围内的键,使事务可以运行在可序列化隔离级别,防止假插入和假删除。 |
|
如果一个事务获取了大量的行锁或页锁,则数据库引擎可能授予它一个表锁,然后释放所有较低级别的锁,以将锁定开销降到最小。 |
|
数据库引擎可以根据优化器估计的 Transact-SQL 语句可能引用的行数,动态地选择锁粒度级别。 |
|
数据库引擎及其相关联的 API 提供了若干机制,用以显示某实例或数据库当前持有的锁的相关信息。 |
|
如果两个任务因均拥有一个对方所需资源的锁而永久互相锁定,就会发生死锁。 |