一.
SQL SERVER 中 為什么要引入鎖
多個用戶同時對數(shù)據(jù)庫的并發(fā)操作時會帶來以下數(shù)據(jù)不一致的問題:
丟失更新
A,B兩個用戶讀同一數(shù)據(jù)并進行修改,其中一個用戶的修改結果破壞了另一個修改的結果,比如訂票系統(tǒng)
臟讀
A用戶修改了數(shù)據(jù),隨后B用戶又讀出該數(shù)據(jù),但A用戶因為某些原因取消了對數(shù)據(jù)的修改,數(shù)據(jù)恢復原值,此時B得到的數(shù)據(jù)就與數(shù)據(jù)庫內(nèi)的數(shù)據(jù)產(chǎn)生了不一致
不可重復讀
A用戶讀取數(shù)據(jù),隨后B用戶讀出該數(shù)據(jù)并修改,此時A用戶再讀取數(shù)據(jù)時發(fā)現(xiàn)前后兩次的值不一致
并發(fā)控制的主要方法是封鎖,鎖就是在一段時間內(nèi)禁止用戶做某些操作以避免產(chǎn)生數(shù)據(jù)不一致
二鎖的分類
鎖的類別有兩種分法:
1. 從數(shù)據(jù)庫系統(tǒng)的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖
MS-SQL Server 使用以下資源鎖模式。
鎖模式 描述
共享 (S) 用于不更改或不更新數(shù)據(jù)的操作(只讀操作),如 SELECT 語句。
更新 (U) 用于可更新的資源中。防止當多個會話在讀取、鎖定以及隨后可能進行的資源更新時發(fā)生常見形式的死鎖。
排它 (X) 用于數(shù)據(jù)修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。
意向鎖用于建立鎖的層次結構。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
架構鎖在執(zhí)行依賴于表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩(wěn)定性 (Sch-S)。
大容量更新 (BU) 向表中大容量復制數(shù)據(jù)并指定了 TABLOCK 提示時使用。
共享鎖
共享 (S)鎖允許并發(fā)事務讀取 (SELECT) 一個資源。資源上存在共享 (S)鎖時,任何其它事務都不能修改數(shù)據(jù)。一旦已經(jīng)讀取數(shù)據(jù),便立即釋放資源上的共享 (S)鎖,除非將事務隔離級別設置為可重復讀或更高級別,或者在事務生存周期內(nèi)用鎖定提示保留共享 (S)鎖。
更新鎖
更新 (U)鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S)鎖,然后修改行,此操作要求鎖轉(zhuǎn)換為排它 (X)鎖。如果兩個事務獲得了資源上的共享模式鎖,然后試圖同時更新數(shù)據(jù),則一個事務嘗試將鎖轉(zhuǎn)換為排它 (X)鎖。共享模式到排它鎖的轉(zhuǎn)換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發(fā)生鎖等待。第二個事務試圖獲取排它 (X)鎖以進行更新。由于兩個事務都要轉(zhuǎn)換為排它 (X)鎖,并且每個事務都等待另一個事務釋放共享模式鎖,因此發(fā)生死鎖。
若要避免這種潛在的死鎖問題,請使用更新 (U)鎖。一次只有一個事務可以獲得資源的更新 (U)鎖。如果事務修改資源,則更新 (U)鎖轉(zhuǎn)換為排它 (X)鎖。否則,鎖轉(zhuǎn)換為共享鎖。
排它鎖
排它 (X)鎖可以防止并發(fā)事務對資源進行訪問。其它事務不能讀取或修改排它 (X)鎖鎖定的數(shù)據(jù)。
意向鎖
意向鎖表示 SQL Server 需要在層次結構中的某些底層資源上獲取共享 (S)鎖或排它 (X)鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (S)鎖。在表級設置意向鎖可防止另一個事務隨后在包含那一頁的表上獲取排它 (X)鎖。意向鎖可以提高性能,因為 SQL Server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。
意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
鎖模式 描述
意向共享 (IS) 通過在各資源上放置 S鎖,表明事務的意向是讀取層次結構中的部分(而不是全部)底層資源。
意向排它 (IX) 通過在各資源上放置 X鎖,表明事務的意向是修改層次結構中的部分(而不是全部)底層資源。IX 是 IS 的超集。
與意向排它共享 (SIX) 通過在各資源上放置 IX鎖,表明事務的意向是讀取層次結構中的全部底層資源并修改部分(而不是全部)底層資源。允許頂層資源上的并發(fā) IS鎖。例如,表的 SIX鎖在表上放置一個 SIX鎖(允許并發(fā) IS鎖),在當前所修改頁上放置 IX鎖(在已修改行上放置 X鎖)。雖然每個資源在一段時間內(nèi)只能有一個 SIX鎖,以防止其它事務對資源進行更新,但是其它事務可以通過獲取表級的 IS鎖來讀取層次結構中的底層資源。
獨占鎖:只允許進行鎖定操作的程序使用,其他任何對他的操作均不會被接受。執(zhí)行數(shù)據(jù)更新命令時,SQL Server會自動使用獨占鎖。當對象上有其他鎖存在時,無法對其加獨占鎖。
共享鎖:共享鎖鎖定的資源可以被其他用戶讀取,但其他用戶無法修改它,在執(zhí)行Select時,SQL Server會對對象加共享鎖。
更新鎖:當SQL Server準備更新數(shù)據(jù)時,它首先對數(shù)據(jù)對象作更新鎖鎖定,這樣數(shù)據(jù)將不能被修改,但可以讀取。等到SQL Server確定要進行更新數(shù)據(jù)操作時,他會自動將更新鎖換為獨占鎖,當對象上有其他鎖存在時,無法對其加更新鎖。
2. 從程序員的角度看:分為樂觀鎖和悲觀鎖。
樂觀鎖:完全依靠數(shù)據(jù)庫來管理鎖的工作。
悲觀鎖:程序員自己管理數(shù)據(jù)或?qū)ο笊系逆i處理。
MS-SQLSERVER使用鎖在多個同時在數(shù)據(jù)庫內(nèi)執(zhí)行修改的用戶間實現(xiàn)悲觀并發(fā)控制