數據庫中的鎖機制
鎖是網絡數據庫中的一個非常重要的概念,它主要用於多用戶環境下保證數據庫完整性和一致性。各種大型數 據庫所采用的鎖的基本理論是一致的,但在具體實現上各有差別。目前,大多數數據庫管理系統都或多或少具有自我調節、自我管理的功能,因此很多用戶實際上不 清楚鎖的理論和所用數據庫中鎖的具體實現。
Microsoft SQL Server(以下簡稱SQL Server)作為一種中小型數據庫管理系統,已經得到了廣泛的應用,該系統更強調由系統來管理鎖。在用戶有SQL請求時,系統分析請求,自動在滿足鎖定 條件和系統性能之間為數據庫加上適當的鎖,同時系統在運行期間常常自動進行優化處理,實行動態加鎖。對於一般的用戶而言,通過系統的自動鎖定管理機制基本 可以滿足使用要求,但如果對數據安全、數據庫完整性和一致性有特殊要求,就必須自己控制數據庫的鎖定和解鎖,這就需要了解SQL Server的鎖機制,掌握數據庫鎖定方法。
鎖的多粒度性以及鎖升級
數據庫中的鎖是指一種軟件機制,用來指示某個用 戶(也即進程會話,下同)已經占用了某種資源,從而防止其他用戶做出影響本用戶的數據修改或導致數據庫數據的非完整性和非一致性。這兒所謂資源,主要指用 戶可以操作的數據行、索引以及數據表等。根據資源的不同,鎖有多粒度(multigranular)的概念,也就是指可以鎖定的資源的層次。SQL Server中能夠鎖定的資源粒度包括:數據庫、表、區域、頁面、鍵值(指帶有索引的行數據)、行標識符(RID,即表中的單行數據)。
采 用多粒度鎖的重要用途是用來支持並發操作和保證數據的完整性。SQL Server根據用戶的請求,做出分析后自動給數據庫加上合適的鎖。假設某用戶只操作一個表中的部分行數據,系統可能會只添加幾個行鎖(RID)或頁面 鎖,這樣可以盡可能多地支持多用戶的並發操作。但是,如果用戶事務中頻繁對某個表中的多條記錄操作,將導致對該表的許多記錄行都加上了行級鎖,數據庫系統 中鎖的數目會急劇增加,這樣就加重了系統負荷,影響系統性能。因此,在數據庫系統中,一般都支持鎖升級(lock escalation)。所謂鎖升級是指調整鎖的粒度,將多個低粒度的鎖替換成少數的更高粒度的鎖,以此來降低系統負荷。在SQL Server中當一個事務中的鎖較多,達到鎖升級門限時,系統自動將行級鎖和頁面鎖升級為表級鎖。特別值得注意的是,在SQL Server中,鎖的升級門限以及鎖升級是由系統自動來確定的,不需要用戶設置。
鎖的模式和兼容性
在數據庫中加鎖時,除了可以對不同的資源加鎖,還可以使用不同程度的加鎖方式,即鎖有多種模式,SQL Server中鎖模式包括:
1.共享鎖
SQL Server中,共享鎖用於所有的只讀數據操作。共享鎖是非獨占的,允許多個並發事務讀取其鎖定的資源。默認情況下,數據被讀取后,SQL Server立即釋放共享鎖。例如,執行查詢“SELECT * FROM my_table”時,首先鎖定第一頁,讀取之后,釋放對第一頁的鎖定,然后鎖定第二頁。這樣,就允許在讀操作過程中,修改未被鎖定的第一頁。但是,事務 隔離級別連接選項設置和SELECT語句中的鎖定設置都可以改變SQL Server的這種默認設置。例如,“ SELECT * FROM my_table HOLDLOCK”就要求在整個查詢過程中,保持對表的鎖定,直到查詢完成才釋放鎖定。
2.修改鎖
修 改鎖在修改操作的初始化階段用來鎖定可能要被修改的資源,這樣可以避免使用共享鎖造成的死鎖現象。因為使用共享鎖時,修改數據的操作分為兩步,首先獲得一 個共享鎖,讀取數據,然后將共享鎖升級為獨占鎖,然后再執行修改操作。這樣如果同時有兩個或多個事務同時對一個事務申請了共享鎖,在修改數據的時候,這些 事務都要將共享鎖升級為獨占鎖。這時,這些事務都不會釋放共享鎖而是一直等待對方釋放,這樣就造成了死鎖。如果一個數據在修改前直接申請修改鎖,在數據修 改的時候再升級為獨占鎖,就可以避免死鎖。修改鎖與共享鎖是兼容的,也就是說一個資源用共享鎖鎖定后,允許再用修改鎖鎖定。
3.獨占鎖
獨占鎖是為修改數據而保留的。它所鎖定的資源,其他事務不能讀取也不能修改。獨占鎖不能和其他鎖兼容。
4.結構鎖
結構鎖分為結構修改鎖(Sch-M)和結構穩定鎖(Sch-S)。執行表定義語言操作時,SQL Server采用Sch-M鎖,編譯查詢時,SQL Server采用Sch-S鎖。
5.意向鎖
意 向鎖說明SQL Server有在資源的低層獲得共享鎖或獨占鎖的意向。例如,表級的共享意向鎖說明事務意圖將獨占鎖釋放到表中的頁或者行。意向鎖又可以分為共享意向鎖、 獨占意向鎖和共享式獨占意向鎖。共享意向鎖說明事務意圖在共享意向鎖所鎖定的低層資源上放置共享鎖來讀取數據。獨占意向鎖說明事務意圖在共享意向鎖所鎖定 的低層資源上放置獨占鎖來修改數據。共享式獨占鎖說明事務允許其他事務使用共享鎖來讀取頂層資源,並意圖在該資源低層上放置獨占鎖。
6.批量修改鎖
批量復制數據時使用批量修改鎖。可以通過表的TabLock提示或者使用系統存儲過程sp_tableoption的“table lock on bulk load”選項設定批量修改鎖。
另外,SQL Server命令語句操作會影響鎖定的方式,語句的組合也同樣能產生不同的鎖定,詳情如下表:
鎖沖突及其防止辦法
在數據庫系統中,死鎖是指多個用戶(進程)分別鎖定了一個資源,並又試圖請求鎖定對方已經鎖定的資源,這就產生了一個鎖定請求環,導致多個用戶(進程)都處於等待對方釋放所鎖定資源的狀態。
在SQL Server中,系統能夠自動定期搜索和處理死鎖問題。系統在每次搜索中標識所有等待鎖定請求的進程會話,如果在下一次搜索中該被標識的進程仍處於等待狀態,SQL Server就開始遞歸死鎖搜索。