在INSERT期间何时启动LOCK

时间:2013-12-09 06:34:34

标签: sql-server

我有一个INSERT statmenet,它通过在SQL Server 2012中执行存储过程来获取数据。

INSERT INTO Employee
EXEC tp_GetEmployees

存储过程大约需要30秒才能提供结果。

  1. 为INSERT引入的锁是否会等待30秒(SP完成)?
  2. 或者仅在sp提供结果后才开始锁定?

2 个答案:

答案 0 :(得分:2)

INSERT语句需要在开始执行之前获取必要的稳定锁(或严格地说,作为执行的第一步)。 INSERT语句包含 EXEC调用,因此EXEC作为执行INSERT的一部分执行,这意味着{{1} }}已经获得了任何必要的稳定性锁(对于INSERT,这必须至少是一个Intent-Exclusive INSERT模式,请参阅intent mode locks)。

数据锁是在插入数据时获取的,否则将是不可能的,因为人们不能简单地猜测将在哪些页面上插入哪些键。由于数据由IX提供,EXEC无法在实际拥有数据之前锁定正在插入的数据。

有关更多详细信息,您可以实时监控锁定获取和释放,例如。见Using XEVENT in SQL Server。监控这些结果还会显示INSERT结果是否被缓冲或插入(这是下一个要问的自然问题)。

答案 1 :(得分:1)

在一个查询窗口中,运行以下命令:

create procedure DoLittle
as
    WAITFOR DELAY '00:05:00'
    select 1 as a
go
create table T (a int not null)
go
insert into T(a)
exec DoLittle
go

在另一个查询窗口中,运行:

sp_lock

哪个应该产生这样的输出(对于运行第一个查询窗口的任何SPID):

spid   dbid   ObjId       IndId  Type Resource                         Mode     Status
------ ------ ----------- ------ ---- -------------------------------- -------- ------
54     1      1623676832  0      TAB                                   IX       GRANT

也就是说,INSERT ... EXEC已经占用了一个Intent eXclusive锁。但没有其他锁。没有其他查询能够获得针对表的eXclusive锁,但是他们可能能够获得更低级别的锁。