一行上的 TSQL 和表鎖
所以我們有一個表被用於跨多個執行緒和程序的並發訪問。對於某些操作,我們希望獲得整個表的排他表鎖,阻止所有訪問,直到操作完成。
以前,我們的一位開發人員這樣做:
SELECT 1 FROM [TableName] (TABLOCKX);
這在我們的桌子很小的時候工作得很好,但是隨著它變大就成了一個問題。
在對這個查詢進行一些研究之後,它似乎為表中的每一行執行一次(
SELECT 1
自然會做什麼),而我們真正想要的是只選擇一行,然後獲取我們的表鎖並儘快退出可能的。然後我建議我們將查詢更改為:
SELECT TOP 1 1 FROM [TableName] (TABLOCKX);
我們對此進行了測試,它似乎有效。執行計劃還認識到這只會觸及 1 行(而前一個觸及所有行)。
我的問題是:這是否按我的想法工作?這將阻止所有操作(包括
NOLOCK
操作)對錶的所有訪問。有一個更好的方法嗎?注意:我們這樣做的原因是我們有一個相當複雜的 .NET 庫,我們正在其中動態建構一些查詢。因為我們希望它們是模組化的,所以我們希望確保開發人員不必自己修改或複制查詢,並且可以在事務開始時簡單地註意到他們將對數據庫進行更新。因此,我們可以製作一個
.LockTables(X)
將鎖定相應組的正確表的單個。
儘管您
WITH (NOLOCK)
的.READ UNCOMMITTED
_WITH (TABLOCKX)
可以在此處找到有關鎖定模式的更多資訊: https ://technet.microsoft.com/en-us/library/ms175519(v=sql.105).aspx
我個人會說,如果您有從表中讀取的查詢,
WITH (NOLOCK)
那麼他們應該完全預期他們會得到不好的結果,因此阻止這些讀取不會是優先事項。如果您的這些查詢需要返回實際正確的數據,那麼他們不應該使用NOLOCK
. https://sqlstudies.com/2015/03/18/why-not-nolock/