2011-12-13 35 views
3

我一直在尋找一段時間,現在在這裏和其他地方,找不到一個很好的答案,爲什麼Linq-TO-SQL與NOLOCK是不可能的。LINQ-TO-SQL NOLOCK(不ReadUncommitted)

每次我搜索如何將(NOLOCK)提示應用於Linq-To-SQL上下文(應用於1個sql語句)時,人們經常會回答強制將IsolationLevel設置爲ReadUncommitted的事務(TransactionScope)。那麼 - 他們很少告訴這導致連接打開一個事務(我也讀過的地方必須確保手動關閉)。

在我的應用程序中原樣使用ReadUncommitted實際上並不好。現在我已經使用上下文語句爲對方內的相同的連接。像:

using(var ctx1 = new Context()) { 
    ... some code here ... 
    using(var ctx2 = new Context()) { 
     ... some code here ... 
     using(var ctx3 = new Context()) { 
      ... some code here ... 
     } 
     ... some code here ... 
    } 
    ... some code here ... 
} 

隨着1秒,很多用戶在同一時間,更改隔離級別的總執行時間,將導致上下文等待對方釋放,因爲在連接池中的所有連接的連接正在使用。

因此,改變爲「nolock」的原因之一是避免死鎖(現在我們每天有1個客戶死鎖)。上述的後果只是另一種僵局,並不能解決我的問題。

所以我知道我可以做的是:同一個連接

    1. 避免嵌套使用在服務器

    增加連接池的大小,但我的問題是:

    1. 這是不可能在不久的將來,因爲許多代碼行重新分解,它會與a (甚至沒有開始評論這是好還是壞)
    2. 即使這當然會起作用,這就是我所說的「症狀治療」 - 因爲我不知道應用程序將會增長多少,以及如果這是對未來的可靠的解決方案(然後我可能最終得到了很多更多的用戶受到影響一個更糟糕的情況)

    我的想法是:

    1. 那麼它是否真的是真實的, NoLock不可能(對於沒有開始事務的每個語句)?
    2. 如果1是真的 - 它真的是真的沒有其他人得到了這個問題,並解決它在一個通用的LINQ sql修改?
    3. 如果2是真的 - 爲什麼這不是別人的問題?
      1. 有沒有另外的解決辦法,我沒有看過可能?
      2. 是否使用相同的連接(嵌套)很多次這麼糟糕的做法,沒有人有這個問題?
  • +1

    是*要被nolocked所有*操作?或*一些*?對於* all *,您可以通過'SET'使用連接級別的隔離級別,但是**重要**;在「輝煌」的舉動,隔離級別** IS NOT **不同的使用相同的底層池連接的,之間的復位,所以如果你走這條路線,你需要明確'SET'適當地打開連接 –

    +1

    之後也:值得一看:http://www.brentozar.com/archive/2011/11/theres-something-about-nolock-webcast-video/ –

    回答

    2

    1:LINQ到SQL確實不允許你表示類似NOLOCK提示;它可能寫你自己的TSQL,但使用ExecuteQuery<T>

    2:以優雅的方式解決將是非常複雜的,坦率地說;而且你很可能會不恰當地使用它。例如,在「僵局」的情景,我敢打賭,實際上它是UPDLOCK,你應該使用(第一次讀期間),以確保第一讀取需要鎖;這可以防止一秒鐘後查詢得到一個鎖,所以你通常得到阻斷,而不是僵局

    3:使用連接不一定是一個很大的問題(但請注意new Context()不會一般共享連接;共享連接,您將使用new Context(connection))。如果遇到這個問題,有三種可能的解決方案(如果我們排除「使用帶有一絲支持的ORM」):使用一個明確的交易(不TransactionScope

    • - 它可以是一個連接級別的事務)來指定隔離級別
    • 編寫自己的TSQL與提示
    • 使用連接級別的隔離級別(注意我添加註釋的警告)

    IIRC還有一種方式分類e數據上下文和一些事務創建代碼來控制它在內部創建的事務的隔離級別。

    +0

    謝謝您的非常好,快回答! –

    +0

    現在我已經用的TransactionScope和this.ExecuteCommand測試(「事務隔離級別設置讀取未提交;」); (當然,我自己的clientcontext類來處理創建和IDisposable通用) 我們確實使用新的上下文(連接)來獲得共享連接的好處.. 使用連接級別的隔離級別,這會影響共享的連接?聽起來像這可能是我的解決方案? –

    +0

    @尼克 - 它是連接寬;該連接的任何用法都將使用最後一個隔離級別集合,它可能意味着來自SET的隔離級別,或者可能意味着事務的隔離級別。瘋狂的事情。和:如前所述它**不**得到自動復位,所以如果你的猴子這一點,那麼** **所有的'connection.Open()'必須發出一個'SET',以確保適當的**隔離*該級別用於該連接。但是 - 只要你明白**你在做什麼(和**爲什麼**),它可以是有效的,是的。 –