SqlServer 使用锁管理器跟踪数据库对象是否被锁住.通常一个查询将锁住一行或者一页,当锁超过一定范围之后,SqlServer尝试将锁升级为表锁来保证对内存的使用.锁升级有时会导致堵塞或者死锁.在SQL Server profiler中我们可以用[Lock:Escalation]事件来跟踪锁的升级.
在SQL Server 2005 中,可以使用跟踪标志 1211 来禁用整个实例中的锁升级.而在SQL Server 2008中,可以使用新的选择来禁止某个表的锁升级
ALTER TABLE SET (LOCK_ECALATION = AUTO | TABLE | DISABLE)
select OBJECT_NAME(object_id) as tab,COUNT(partition_number) as part
from sys.partitions
where index_id in(0,1)
and OBJECT_NAME(object_id) notlike'conflict%'
and OBJECT_NAME(object_id) notlike'sys%'
and OBJECT_NAME(object_id) notlike'MS%'
groupby object_id
orderby tab
-- 批量设置表选项——启用锁升级到分区
DECLARE @tbName VARCHAR(50)
DECLARE cur SCROLLCURSOR
FOR
select OBJECT_NAME(object_id) as tab
from sys.partitions
where index_id in(0,1)
and OBJECT_NAME(object_id) notlike'conflict%'
and OBJECT_NAME(object_id) notlike'sys%'
and OBJECT_NAME(object_id) notlike'MS%'
groupby object_id
havingCOUNT(partition_number)>1
orderby tab
OPEN cur
FETCHNEXTFROM cur INTO @tbName
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ('ALTER TABLE [dbo].['+@tbName+'] SET (LOCK_ESCALATION = AUTO); ')
FETCHNEXTFROM cur INTO @tbName
END
CLOSE cur
DEALLOCATE cur
附加说明: 触发锁升级:(数据库引擎不会将行锁或键范围锁升级到页锁,而是将它们直接升级到表锁) A 单个 Transact-SQL 语句在单个无分区表或索引上获得至少 5,000 个锁 B 单个 Transact-SQL 语句在已分区表的单个分区上获得至少 5,000 个锁,并且 ALTER TABLE SET LOCK_ESCALATION 选项设为 AUTO C 数据库引擎实例中的锁的数量超出了内存或配置阈值 D 如果由于锁冲突导致无法升级锁,则数据库引擎每当获取 1,250 个新锁时便会触发锁升级