程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> MS SQL Update鎖介紹

MS SQL Update鎖介紹

編輯:關於SqlServer
 

UPDATE 鎖並不是一種單獨的鎖類型,倒是有點像是SHARED和EXCLUSIVE鎖的混合。並且可能與你認為的不同,UPDATE 鎖不是由UPDATE操作獲取的。 當SQL Server執行一個數據修改操作,但是需要首先執行一個檢索來查找需要修改的資源時,事務會獲取這種類型的鎖。

當SQL Server搜索時,它不需要獲取EXCLUSIVE鎖,只有在找到要更改數據時,才需要EXCLUSIVE鎖。通常情況下,如果SQL Server進程只是搜索數據,它會在所訪問到的每個資源上獲取SHARED鎖,然後確定是否已經找到了正在搜索的數據。但是,如果要搜索的數據是用來修改的話,SQL Server啟用SHARED鎖則存在潛在問題。例如,兩個進程都是尋找相同的資源(如Customers表中同一客戶行)進行修改,使用不同的訪問的路徑,並且它們在同一時間達到所需的資源。如果它們都在檢索的數據上獲取SHARED鎖,它們都可以同時鎖定要修改的資源,但在它們進行修改前需要將鎖轉換為EXCLUSIVE鎖。 由於另一個進程具有了SHARED鎖,則不會生成EXCLUSIVE鎖。 每個進程都具有一個SHARED鎖,並且每個都嘗試將其轉換為EXCLUSIVE的鎖,但是都會由於另外一個進程的存在,這兩個嘗試都不會成功。這是一種死鎖情況,叫做“轉換死鎖”。

UPDATE 鎖是一種死鎖避免機制。如果SQL Server使用UPDATE鎖,則死鎖將不會發生。 如果SQL Server進程開始了一個最終要修改數據的搜索操作,它獲取UPDATE鎖,直到找到要修改的數據。 UPDATE 鎖與SHARED鎖兼容,但與EXCLUSIVE鎖或其他UPDATE鎖不兼容。 因此,如果兩個進程正在尋找相同的數據資源,則第一個到達的進程會獲取到UPDATE鎖,然後在第二個進程無法取得任何鎖定,並且將等待第一個進程處理完成。由於第一個進程沒有被阻塞,它可以將其UPDATE鎖轉換為EXCLUSIVE鎖,並完成事務處理後釋放鎖,然後在第二個進程進行其他修改。

在 sys.dm_tran_locks 視圖中,request_mode值為U的代表 UPDATE 鎖。

來看一下UPDATE鎖:

[我正在使用舊的示例數據庫 pubs。 如果要嘗試下面的代碼可以單擊這裡下載]。

-- Close all existing connections and start a new one

-- Step 1: 
USE pubs; 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;


BEGIN TRAN; 
UPDATE authors 
SET contract = 0 
WHERE au_lname = 'Ringer' ;

---- Step 2: Open a second connection window uncomment once, 
--   so the ROLLBACK is still commented. Execute…

--USE pubs; 
--SET TRANSACTION ISOLATION LEVEL READ COMMITTED ;

--BEGIN TRAN; 
--UPDATE  authors 
--SET city = 'Provo' 
--WHERE  state = 'UT';

-- You should be blocked.

---- ROLLBACK TRAN;

-- Step 3: Go back to the first connection window and run the following 
SELECT request_session_id AS session_id, DB_NAME(resource_database_id) AS [database], 
   request_mode AS mode, resource_type as [type],  
   resource_associated_entity_id AS entity, 
   resource_description,  request_status AS status 
FROM sys.dm_tran_locks; 
COMMIT TRAN;

你將會得到類似下面的輸出結果:

 

注意KEY為WAIT狀態的U鎖,它具有與第一個連接所GRANT的KEY相同的資源描述。現在COMMIT或ROLLBACK第一個連接,你會看到第二個連接所等待的KEY上獲得X鎖,還有在另一個KEY上的X鎖。

 

我提及UPDATE鎖的目的是說明“修改數據的意向”,因此你可能會認為UPDATE的鎖是類似於INIENT鎖。 不是這樣的,UPDATE鎖指示一個更改鎖鎖模式的意向,而INTENT鎖指示一個更改鎖粒度的意向。

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved