
SQLServer 使用锁管理器跟踪数据库对象是否被锁住,通常一个查询将锁住一行或者一页。当锁超过一定范围之后,SQLServer 尝试将锁升级为表锁来保证对内存的使用,锁升级有时会导致堵塞或者死锁。在SQL Server profiler中我们可以用 [Lock:Escalation] 事件来跟踪锁的升级。
在SQL Server 2005 中,可以使用跟踪标志 1211 来禁用整个实例中的锁升级。而在SQL Server 2008中,可以使用新的选择来禁止某个表的锁升级。
ALTER TABLE SET (LOCK_ECALATION = AUTO | TABLE | DISABLE)
| AUTO | 此选项允许 SQL Server 数据库引擎选择适合于表架构的锁升级粒度。 |
| (AUTO:如表已分区,将使用分区的hobt锁,但并发情况增加。) | |
| 如果该表已分区,则允许将锁升级到分区。锁升级到分区级别之后,该锁以后将不会升级到 TABLE 粒度。 | |
| 如果该表未分区,则会将锁升级到 TABLE 粒度 | |
| TABLE | 无论表是否已分区,都会在表级粒度完成锁升级。 默认值为 TABLE |
| DISABLE | 在大多数情况下禁止锁升级。 表级别的锁未完全禁止。 |
| 例如,当扫描在可序列化隔离级别下没有聚集索引的表时,数据库引擎必须使用表锁来保证数据的完整性。 |
经过几次插入数据测试,使我要更改的这个条件的数据达到6500行,这样才进行锁升级。否则键锁和页锁非常多。
--分区1:6500行select COUNT(*) from dbo.AABB where $partition.pf_sid(sid)=1--先测试表:TABLEALTER TABLE dbo.AABB SET (LOCK_ESCALATION = TABLE);--查看锁begin tranupdate dbo.AABB set num=1where sid=0x0105000000000005150000002B5CA2768377FDF37E993215F4010000SELECT resource_type,resource_subtype,resource_description,request_mode,resource_associated_entity_idfrom sys.dm_tran_lockswhere resource_database_id=DB_ID() and request_session_id=@@SPIDorder by resource_type,resource_descriptionrollback tran

图一
可以看到,对象表使用了排他锁,这样整个表都不能访问了!
--再测试表:AUTOALTER TABLE dbo.AABB SET (LOCK_ESCALATION = AUTO);

图二
其他说明:
触发锁升级:(数据库引擎不会将行锁或键范围锁升级到页锁,而是将它们直接升级到表锁)
单个 Transact-SQL 语句在单个无分区表或索引上获得至少 5,000 个锁
单个 Transact-SQL 语句在已分区表的单个分区上获得至少 5,000 个锁,并且 ALTER TABLE SET LOCK_ESCALATION 选项设为 AUTO
数据库引擎实例中的锁的数量超出了内存或配置阈值
如果由于锁冲突导致无法升级锁,则数据库引擎每当获取 1,250 个新锁时便会触发锁升级
最近文章推荐:
历史文章推荐:

文章转载自SQLServer,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




