KB2448971-修复:当你在 SQL Server 2008 或 SQL Server 2008 R2 中将多行插入到表中时,表的锁不会升级

适用于: Microsoft SQL Server 2008 Service Pack 4Microsoft SQL Server 2008 R2 Service Pack 3

症状


请考虑以下情况:
  • 在 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 语句返回值 12。 如果表的锁未升级,则最后一个 SELECT 语句返回值为 4006640067