1

有了由脚本 [1] 定义的表,我在 SSMS 的 2 个窗口中执行脚本

--1) first in first SSMS window
set transaction isolation level READ UNCOMMITTED;
begin transaction;
update aaa set Name ='bbb' 
    where id=1;
-- results in "(1 row(s) affected)"
--rollback

1)之后

--2)after launching 1)
select * from aaa --deleted comments
where id<>1
--is blocked

独立于 1) 窗口中的事务隔离级别,2) 中的 SELECT 被阻塞。
为什么?

UPDATE 的隔离级别对其他事务的语句有影响吗?

最高隔离级别是 2) 中默认的 READ COMMITTED。
不归属范围锁,SELECT 应该遭受 COMMITTED READS (NONREPEATABLE READs) 和 PHANTOM READS (Repeatable Reads) 问题 [2]
如何让它遭受痛苦?

如何在不阻塞 SELECT 的情况下进行 UPDATE?

[1]

CREATE TABLE aaa
(
    Id int IDENTITY(1,1) NOT NULL,
    Name  varchar(13) NOT NULL
)


insert into  aaa(Name) 
   select '111' union all 
   select '222' union all 
   select '333' union all 
   select '444' union all 
   select '555' union all 
   select '666' union all 
   select '777' union all 
   select '888'  

[2]单击http://en.wikipedia.org/wiki/Isolation_(database_systems )
后复制&粘贴或添加尾随)

更新:
SELECT WITH(NOLOCK) 未被阻止...

更新2:
或与,有什么相同,阅读未提交

请注意,UPDATE 与 SELECT 行不同。
即使在相同的情况下,这种行为也与隔离级别的描述相矛盾 [2]

要点是:

  • 假设我不知道还有谁将从同一个(UPDATE-d)表中选择,但与更新行无关
  • 了解隔离级别 [2]

SQL Server 2008 R2 开发

4

2 回答 2

6

我相信这是因为您没有主键,我认为这会导致锁升级,从而阻止 SELECT。如果您在 ID 列上添加 PRIMARY KEY,您会注意到,如果您再试一次,SELECT 现在将返回其他 3 行 - 不需要 WITH (NOLOCK) 提示。

于 2010-10-24T21:58:23.453 回答
2

之后重复测试

--3)
create index IX_aaa_ID on aaa(id)

SELECT 2) 仍然被阻止

--4)
drop index IX_aaa_ID on aaa
create unique index IX_aaa_ID on aaa(id)
--or adding primary key constraint   

SELECT 2) 未被阻止

如果将 2) 修改为

--2b)
select * from aaa 
    where id=3 
    --or as
    --WHERE id=2 

表明即使没有任何索引或 PK,2b) 也不会被阻止。

虽然,2b),没有任何索引,在修改 1) UPDATE 以在可序列化但不在 REPEATABLE READ 或更低版本下运行后被阻止

--1c)  
set transaction isolation level serializable;
--set transaction isolation level REPEATABLE READ;

begin transaction;
update aaa set Name ='bbb' 
    where id=1;
--rollback

那么,看起来多行选择尝试获取不可共享锁?

更新:
好吧,在所有 SELECT 被阻止的情况下,它都在等待获取 LCK_M_IS
很好的理由来理解这道菜

更新2 :
嗯,不是在表上升级了UPDATE锁,而是SELECT(共享)锁(当SELECT尝试读取多行时)升级为表锁并且无法授予,因为表已经排他(UPDATE)锁。

索引的存在与否与我的主要问题无关

我将此主题的讨论转移到我提交的建议“如果表已包含独占锁,则不应将意图行锁升级为表锁”

于 2010-10-25T02:25:58.560 回答