SqlServer查詢語句中用到的鎖程序員
做者: wokofosql
前段時間**公司DBA來咱們這培訓。講了一大堆MYSQL的優化。 QA環節一程序員問「SQL語句中的 with nolock 除了不鎖表外,是否能讀其餘鎖住的數據"。數據庫
講課的人嘟嘟了半天沒解釋清楚(有多是MYSQL裏沒有這個機制),公司的另外一程序員給出了一個很簡潔明瞭的回答:優化
WITH NOLOCK 除了自己不鎖表(不加任何鎖) 也不會受其餘的已存在的鎖影響, 鎖住的行數據也照樣讀,server
我的認爲這句話說得很清楚明瞭,一句話就能說明白的事,不過好奇怪的是程序員常常用這個語句居然也不去試一下。 這裏順便總結一下 其餘的 SQLSERVER 中的with鎖級別:對象
WITH NOLOCK:無鎖進程
WITH HOLDLOCK:掛一個保持鎖事務
WITH UPDLOCK:掛一個更新鎖it
WITH XLOCK:掛一個排他鎖io
須要注意的是 with nolock 是不能用於update,delete insert 這種更新語句的,說繞了。簡單的說 with nolock 只能用於select。
例如:update dbo.test with(NOLOCK) set username='wokofo' --這樣的語句是錯誤的
彈回:INSERT、UPDATE、DELETE 或 MERGE 語句的目標表不容許使用 NOLOCK 和 READUNCOMMITTED 鎖提示。
實際使用:
selecttop10*from dbo.test with(NOLOCK) selecttop10*from dbo.test with(HOLDLOCK) selecttop10*from dbo.test with(XLOCK) selecttop10*from dbo.test with(UPDLOCK) update dbo.test with(HOLDLOCK) set username='wokofo' update dbo.test with(XLOCK) set username='wokofo' update dbo.test with(UPDLOCK) set username='wokofo'
NOLOCK(不加鎖)
此選項被選中時,SQL Server 在讀取或修改數據時不加任何鎖。 在這種狀況下, 用戶有可能讀取到未完成事務(Uncommited Transaction)或回滾(Roll Back)中的數據, 即所謂的「髒數據」。
HOLDLOCK(保持鎖)
此選項被選中時,SQL Server 會將此共享鎖保持至整個事務結束,而不會在途中釋放。
UPDLOCK(修改鎖)
此選項被選中時,SQL Server 在讀取數據時使用修改鎖來代替共享鎖, 並將此鎖保持至整個事務或命令結束。使用此選項可以保證多個進程能同時讀取數據但只有該進程能修改數據。
TABLOCK(表鎖)
此選項被選中時,SQL Server 將在整個表上置共享鎖直至該命令結束。 這個選項保證其餘進程只能讀取而不能修改數據。
PAGLOCK(頁鎖)
此選項爲默認選項, 當被選中時,SQL Server 使用共享頁鎖。
TABLOCKX(排它表鎖)
此選項被選中時,SQL Server 將在整個表上置排它鎖直至該命令或事務結束。這將防止其餘進程讀取或修改表中的數據。
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不須要時當即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,容許髒讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨佔表級鎖,這個鎖在事務期間阻止任何其餘事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
注意: 鎖定數據庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其餘事務能夠讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其餘事務不能讀取表,更新和刪