Sql-Server

一行上的 TSQL 和表鎖

  • December 6, 2016

所以我們有一個表被用於跨多個執行緒和程序的並發訪問。對於某些操作,我們希望獲得整個表的排他表鎖,阻止所有訪問,直到操作完成。

以前,我們的一位開發人員這樣做:

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/

引用自:https://dba.stackexchange.com/questions/157291