2010-10-24 55 views
1

具有表,由脚本定义的[1],我的SSMS为什么更新块在无关行上选择?

--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 

2个窗口和1之后)

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

执行独立于在1)窗口的事务隔离级别的脚本,该SELECT in 2)被阻止。
为什么?

更新的隔离级别是否对其他事务的语句有任何影响?

最高隔离级别是2)中的默认READ COMMITTED。
没有范围锁定,SELECT应该遭受COMMITTED READS(不可重复读取)和PHANTOM 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)不被阻挡.. 。

Update2:
或与,什么是相同的,请阅读未提及

请注意,UPDATE与SELECT行不同。
甚至,如果在同一个,这种行为违背了隔离级别的描述[2]

点在于:

  • 想我不知道还有谁将会从相同的选择(UPDATE -d)表,但对无关的更新行时
  • 理解隔离级别[2]

的SQL Server 2008 R2开发

+0

WITH(NOLOCK)块选择? – 2010-10-24 20:52:33

+0

你是不是故意用“ - ”提示? – 2010-10-24 20:53:48

+0

如果您使用rowlock更新提示,该怎么办? (并假设它没有升级......) – 2010-10-24 21:20:21

回答

6

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

2

重复测试

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

选择2)仍然受阻

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

选择2)不被阻挡

如果修改2)

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

表明2b)不是即使没有任何指数或PK也会被封锁。

虽然,2b)中,而没有任何索引,被修改1)UPDATE到下序列 运行,但没有下重复读或低级

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

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

所以,它看起来像的多个行选择尝试获取之后阻断非共享锁?

更新:
那么,在选择的所有情况下被阻止它正在等待获取LCK_M_IS
很好的理由uderstand这个菜

UPDATE2:
嗯,这是不更新锁将升级在表上,它是SELECT(共享)锁(当SELECT尝试读取多行时)被升级为表锁并且不能被授予,因为表已经具有独占(UPDATE)锁。

而且存在或不存在指数无关我的首要问题

我这个话题的讨论转移到我提交建议"Intent rowlocks should not be escalated to a table lock if a table already contains exclusive lock"

相关问题