2012-11-02 63 views
0

我試圖在查看頁面的人(它增加查看的計數)時更新表中的一行,但是現在然後我得到一個死鎖錯誤,我猜這是由於到兩個或更多的人試圖更新同一行?SQL - 導致死鎖錯誤的更新

的錯誤是:

Transaction (Process ID 60) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

我的SQL是:

UPDATE [ProductDescription] 
SET [ViewCount] = ([ViewCount] + 1) 
WHERE ProductCode = @prodCode 
    AND ApplicationID = @AppID 

我認爲我可能需要WITH(NOLOCK)?

+0

您應該從[使用SQL Server Profiler分析死鎖]開始(http://msdn.microsoft.com/en-us/library/ms188246(v = sql.100).aspx) –

+0

不要使用WITH (NOLOCK)',你應該考慮檢查你的事務隔離級別和索引。正確的索引可以減少爭用。 –

+0

謝謝,我添加了一個索引,希望能大大減少錯誤! – dhardy

回答

-1

事務隔離級別設置爲SERIALIZABLE或快照更新數據properly.For詳情檢查HERE

+0

Seriazizable可能會導致進一步的死鎖,因爲鎖將保持到交易結束 –

+0

請參閱每次更新都將在交易中進行更新,其他更新將等待完成第一個更新。如何進一步鎖定您是否可以解釋? – AnandPhadke

+0

如果事務在訪問其他表之後訪問另一個表,並且其他事務首先訪問了不同的表 –

0

你不需要NOLOCK。這隻會刪除讀鎖,並會導致不可預知的結果。更好的做法是在update語句上使用TABLOCK,這意味着其他進程在完成之前無法訪問表。

+0

我同意'WITH(NOLOCK)'不好,但肯定'ROWLOCK'不會使其它進程無法訪問**表**直到完成。* TABLOCKX'會實現這個目標,不是嗎? –

+0

是的,錯字,編輯!謝謝 –

+0

「WITH(NOLOCK)很糟糕」。真?看看他們在任何地方使用的一些內置系統SP。還要考慮到這相當於READ UNCOMMITTED。它只是一個不同的粒度級別 - 僅此而已。 –

-1

問題更可能是由用戶同時運行選擇引起的。默認隔離級別是「讀取已提交」,這會導致鎖定。

除非是至關重要的,你正在閱讀的數據是最新的,可以考慮使用:

with(nolock) 
在選擇

或替代隔離級別。

+0

除非您正在執行諸如填充下拉列表之類的操作,否則NOLOCK總是失去一個好主意。請記住,這不僅僅是因爲你可以閱讀髒數據,你也可以得到重複的結果等,因爲頁面混洗 –

+0

DB編程中絕對數量很少,WITH(NOLOCK)就是其中之一。您需要仔細考慮您是否關心陳舊的數據。大多數時候你沒有。看到這裏:http://stackoverflow.com/questions/1452996/is-the-nolock-sql-server-hint-bad-practice –

+0

我當然不建議把他們像紙屑扔。如果你有很多不斷更新和閱讀的表,你需要查看隔離級別。 –