https://www.cnblogs.com/sthinker/p/5922967.html
SqlServer查詢語句中用到的鎖
作者: wokofo
前段時間**公司DBA來我們這培訓。講了一大堆MYSQL的優化。 QA環節一程序員問“SQL語句中的 with nolock 除了不鎖表外,是否能讀其他鎖住的數據"。
講課的人嘟嘟了半天沒解釋清楚(有可能是MYSQL里沒有這個機制),公司的另一程序員給出了一個很簡潔明了的回答:
WITH NOLOCK 除了本身不鎖表(不加任何鎖) 也不會受其他的已存在的鎖影響, 鎖住的行數據也照樣讀,
個人認為這句話說得很清楚明了,一句話就能說明白的事,不過好奇怪的是程序員經常用這個語句竟然也不去試一下。 這里順便總結一下 其他的 SQLSERVER 中的with鎖級別:
WITH NOLOCK:無鎖
WITH HOLDLOCK:掛一個保持鎖
WITH UPDLOCK:掛一個更新鎖
WITH XLOCK:掛一個排他鎖
需要注意的是 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) 其他事務不能讀取表,更新和刪