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

use*_*567 6 sql sql-server sql-server-2008-r2

我运行了这个SQL,

create table temp
(
     id int,
    name varchar(10)
)
insert into temp values(1,'a');
Run Code Online (Sandbox Code Playgroud)

然后我跑,

select 1 from temp  where id = 1 
Run Code Online (Sandbox Code Playgroud)

一切都很好.

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

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



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

insert into temp values(2,'b')
Run Code Online (Sandbox Code Playgroud)

然后我跑,

select 1 from temp  where id = 1 
Run Code Online (Sandbox Code Playgroud)

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

usr*_*usr 6

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

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

在此输入图像描述

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

在此输入图像描述 会话51已插入id 2.会话54是被阻止的选择.这里没有页面或表锁(除了意图锁在这里无关紧要).

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