Sql-Server

數據庫級鎖

  • November 30, 2017

我有一個 SQL Server 2014 的生產實例,我需要對其進行一些輕度維護。

本質上,我需要在一個事務中替換兩個完整表的內容。我想防止任何人在數據更改正在進行時查詢任一表。這些表很小,我預計該操作將花費不到幾秒鐘的時間。

不幸的是,我沒有為此安排停機時間。

所以問題是我怎樣才能一次鎖定多個對象——甚至整個數據庫?

理想情況下,我可以簡單地獲取數據庫級別的鎖,進行更改並釋放鎖,但這在 SQL Server 2014 中似乎是不可能的。

您可以首先使用帶有 UPDLOCK 的查詢,以保護您免受整個事務中的所有內容(臟讀除外)。

它永遠不可能是單個鎖,因為單個鎖不能跨越對象。但是我仍然相信這可以實現您所追求的,只要您沒有查詢 NOLOCK (如果您這樣做,您將得到您所要求的!)。

BEGIN TRANSACTION;

SELECT pkcol FROM dbo.foo WITH (UPDLOCK, HOLDLOCK)
UNION ALL
SELECT pkcol FROM dbo.bar WITH (UPDLOCK, HOLDLOCK);

-- do other stuff

UPDATE dbo.foo SET ...;
UPDATE dbo.bar SET ...;

-- do other stuff

-- default isolation level users will be blocked until:
COMMIT TRANSACTION;

有可能使用 NOLOCK,使用者可以在中間潛入並從兩個表中查詢,並在更新後從第一個表和更新前的第二個表中獲取數據。但是,當您允許 NOLOCK 時,這就是您所得到的。

也有可能在某個時候,預設隔離級別下的使用者可以查詢bar並查看值,但他們會阻止foo.

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