症状
请考虑以下情况:
-
在 Microsoft SQL Server 2008 或 SQL Server 2008 R2 中使用以下查询之一将多行插入到表中:
-
INSERT INTO <target_table> SELECT * FROM <target_table> WHERE <predicate>
-
SELECT * INTO <target_table> FROM <source_table> WHERE <predicate>
注意
-
<target_table>占位符表示实际的目标表名称。
-
<谓语>占位符表示实际谓语。
-
<source_table>占位符表示实际源表。
-
-
超过了表的锁升级阈值。
在这种情况下,数据库引擎不会提升表的锁。
原因
出现此问题的原因是 SQL Server 不会内部计算由 INSERT 操作生成的所有新锁。 因此,在需要时,可能不会触发锁升级阈值。
解决方案
SQL Server 2008 的 Service pack 信息
若要解决此问题,请获取最新的 SQL Server 2008 service pack。有关详细信息,请单击下面的文章编号以查看 Microsoft 知识库中的文章:
968382 如何获取最新的 SQL Server 2008 服务包
SQL Server 2008 R2 的 Service pack 信息
若要解决此问题,请获取最新的 SQL Server 2008 R2 服务包。有关详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2527041如何获取最新的 SQL Server 2008 R2 服务包
状态
Microsoft 已确认这是在“适用范围”部分中列出的 Microsoft 产品存在的问题。此问题首先在 sql server 2008 Service Pack 2 for SQL Server 2008 中更正。此问题首先在 sql server 2008 R2 Service Pack 1 for SQL Server 2008 R2 中更正。
更多信息
有关锁升级的详细信息,请访问以下 Microsoft TechNet 网站:
有关锁升级的常规信息若要确定是否升级了表的锁,请运行以下 Transact-sql 语句:
USE tempdbGOCREATE TABLE x (i INT NOT NULL PRIMARY KEY)GOBEGIN TRANINSERT xSELECT TOP (40000)ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rFROM master..spt_values a, master..spt_values bORDER BYrSELECTCOUNT(*)FROM sys.dm_tran_locksWHERE request_session_id = @@SPID ROLLBACKGODROP TABLE x
如果表的锁已升级,则最后一个 SELECT 语句返回值 1 或 2。 如果表的锁未升级,则最后一个 SELECT 语句返回值为 40066 或 40067。