SQL Server 中的 NOLOCK 到底是什麼意思?

天豪發表於2018-06-04

  以前遇到過,但僅限於聽同事說加上NOLOCK好一些,今天仔細研究測試了下,終於理解了,那麼加與不加到底區別在哪呢?

    我先說下其區別,之後再做測試。

    大家都知道,每新建一個查詢,都相當於建立一個會話,在不同的查詢分析器裡面進行的操作,可以影響到其他會話的查詢,極端的情況可能會一直處於阻塞中,哪怕只是一個很簡單的查詢都“特別慢”。

    BEGIN TRAN 是開始一個事務的意思,開始之後可執行一些SQL語句,接著需要執行COMMIT進行提交或者ROLLBACK進行回滾,否則就會出現上面的情況。但如果使用NOLOCK進行查詢的時候,就不會因為別的回話沒有提交或回滾,而受阻塞。所以概括起來,可以用以下語句來總結:

    NOLOCK能使當前會話的查詢,不受其它會話的事務所阻塞。但是這樣做,就讀取了其它事務的“修改後未提交的”資料。

    現在我們進行測試,一定要注意,必須在多個會話下才可以,也就是說,需要建三個查詢分析器視窗。

    表用最簡單的表,自己動手建一個。

    查詢分析器一:執行

       SELECT * FROM dbo.test_main

       得到

        id    value
        1     one
        2     two
        3     three
        4     four

       接著執行如下:

       BEGIN TRAN
       INSERT INTO test_main VALUES(5, `five`)

       一行受影響   

    查詢分析器二:執行

      SELECT * FROM dbo.test_main

      則卡死,受上一會話所阻塞。查不出結果。

      補充:那麼卡死怎麼辦呢?我們已經說過,要執行提交或者回滾操作才可以,那麼在會話一中執行COMMIT即可。 之後此查詢立刻顯示結果。

    查詢分析器三:執行

       SELECT * FROM test_main(NOLOCK)

      則顯示如下

       id    value
        1     one
        2     two
        3     three
        4     four

        5     five

       但最後一行並沒有真正儲存在資料庫中,因為會話一還沒有進行提交,我們用NOLOCK就查詢出來了。

  也許你會想,那什麼情況下用NOLOCK呢?經過我們的分析,用NOLOCK是為了避免出現卡死狀態,那我們就可以分析其環境了。

  一個經常操作的表,並且每次操作都很重要,這樣一般要用到事務進行處理,因為可以避免出錯的機率,

我們查詢時,要用NOLOCK,否則遇上卡死的機率很大。別人執行一個事務,還沒處理完呢,你就查詢了,那就卡死了。有了NOLOCK就可以解決這個問題了。

相關文章