2010-10-24 58 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"

相關問題