为什么我的完整表被锁定而不是行?

时间:2013-12-03 18:32:44

标签: sql sql-server sql-server-2008-r2

我已经运行了这个SQL,

create table temp
(
     id int,
    name varchar(10)
)
insert into temp values(1,'a');

然后我跑,

select 1 from temp  where id = 1 
一切都很好。

然后我运行一个未提交的插入

SET NOCOUNT ON;
    DECLARE @TranCount INT;
    SET @TranCount = @@TRANCOUNT;



        IF @TranCount = 0
            BEGIN TRANSACTION
        ELSE
            SAVE TRANSACTION Insertorupdatedevicecatalog;

insert into temp values(2,'b')

然后我跑,

select 1 from temp  where id = 1 

但这次没有任何回复。为什么我的完整表被锁定而不仅仅是第二行?

2 个答案:

答案 0 :(得分:6)

SQL Server没有锁定整个表。我可以看到写入事务锁定了单个row-id。

读者必须扫描整个表,因为没有索引。

enter image description here

这意味着它被插入行上的X锁定阻止。基本上,读者等待另一个事务来决定是否要实际提交此行或回滚。

enter image description here 会话51已插入id 2.会话54是被阻止的选择。这里没有页面或表锁(除了这里没关系的意图锁)。

表是堆的事实(没有像通常那样的唯一CI)会导致意外锁定。通过在ID上创建唯一的CI,此问题将消失。

答案 1 :(得分:2)

我的猜测是你的桌子本身可能没有被锁定(或者可能是因为你的行数很少)。我认为发生的事情是SQL Server为了知道在哪里插入新行,必须锁定(写锁定,这会阻止读取)插入值周围的一系列行。由于表中的行数很少,因此表格是锁定的。当您添加更多行时,插入单行时不应该看到此行为。

顺便说一句,您的表应该有一个主键和/或聚簇索引。这将有助于将来添加更多行。否则你将进行扫描,这肯定会延长进行更新(也许是插入)所需的时间。