2012-01-09 63 views
5

我正在使用多線程應用程序(C#),並且2個線程同時使用NOLOCK更新表,這是一個問題嗎?更具體地說,他們都在更新相同的記錄。NOLOCK與多線程

+3

知道何時使用NOLOCK需要深入瞭解SQL Server如何,何時以及爲何鎖定了什麼。它不應該隨便使用。如果你不得不問這個問題,你可能根本不應該使用NOLOCK。 – 2012-01-09 19:14:19

+1

當你只想做一個髒讀時,NOLOCK將忽略作者所持有的鎖! – 2012-01-09 19:18:29

+0

如果我知道nolock,我不會問:)這是應用程序在我的工作中的實現方式,我正在調試這個問題。無論在任何查詢中他們都使用nolock。我們有近800個存儲過程。 – fbhdev 2012-01-09 20:04:46

回答

4

答案是「視情況而定」。

NOLOCK允許「髒讀」。這意味着在交易內,您可能會看到來自其他交易的未提交數據。如果您有多個線程更新同一個表中的同一行,您可能會看到其他線程在修改事務之前所修改的數據值。

例如,將表account_balances定義爲(account_num int,balance decimal(12,2))。讓我們假設會發生以下情況:

//前提下,賬戶#1有10.00

  1. 線程#平衡1開始交易,遞減10
  2. 線程#2開始一個交易賬戶#1 ,嘗試讀取帳戶#1的餘額。它讀取的0
  3. 線程#2的平衡減$ 5的帳戶,併發出透支給客戶(他們的平衡-5)
  4. 線程#1回滾它的事務
  5. 線程#2提交它的交易

//帳戶餘額現在是-5,即使它應該是5.

什麼你不會看到的是一個現場NOLOCK提示中的某種形式的數據不一致的不像在運行多線程代碼鎖 - 個人寫入仍然是原子的。

+1

即使在'read uncommitted'下,編寫者也會阻止編寫者。因此,線程2將無法更新行,直到線程1的事務完成。除此之外,這是現貨。 – zinglon 2012-01-09 19:53:15

+0

已修復,感謝您的支持 – 2012-01-09 19:55:59

+0

因此,如果我期望列中有1,並且它顯示爲2,那麼它可能是線程競賽而不是與nolock有任何關係? – fbhdev 2012-01-09 20:08:15

2

這意味着您可以獲取處於「錯誤」狀態的記錄。

例如...

  • 處理1被刪除數據
  • 過程2被讀取的數據的重疊塊的塊,使用NOLOCK

在理想情況下,無論是全部由Process1刪除的記錄可能存在或被刪除。因爲Process2正在使用NOLOCK,所以它可能會讀取某些 Process1正在刪除的記錄,但不是其他人,因爲它們已經消失。

INSERTS和UPDATES也是如此。您可能只是通過以某種方式進行修改來閱讀只是其中一部分的記錄。


這是否是一個問題,取決於你的數據,你的設計等

搜索引擎不會在乎如果發生這種情況。一家銀行負責金融交易。

0

即使使用NOLOCK提示,也不能同時更改相同的記錄。

你可以把數據變成不一致的狀態。

AFAIK - 無法將此提示應用於目標更新表。

而且 - 這暗示讓你閱讀未提交的數據,不覆蓋他們。

0

小心你如何使用它。潛在的數據不一致。

如果一個查詢是 與(NOLOCK)其中可樂= 「colAOldvalue」

而另一查詢是 組COLC = 「colCnewValue」 從表A與(NOLOCK)其中可樂設置可樂= 「newColANewvalue」 從表A =「colAOldvalue」

您可以在同一條記錄上以colC =「colCnewValue」和colA =「newColANewvalue」結束。如果這不是問題,那麼確定。

這是什麼驅動?你是否遇到了rowlock或pagelock的性能問題?