前言:本章討論多個SQL語句同時執行的必要性和所需的基礎設施。
鎖
鎖是數據庫服務器用來控制數據被並行使用的一種機制。當數據庫的一些內容被鎖定時,任何打算修改(或者可能是讀取)這個數據的用戶必須等到鎖釋放。大部分數據庫使用以下兩種鎖策略之一。
策略一:數據庫的寫操作必須向服務器申請並獲得寫鎖才能修改數據,而讀操作必須申請和獲得讀鎖才能查詢數據。多用戶可以同時讀取數據,而一個表(或其他部分)一次只能分配一個寫鎖,並且拒絕讀請求直至寫鎖釋放。
策略二:數據庫的寫操作必須向服務器申請並獲得寫鎖才能修改數據,而讀操作不需要任何類型的鎖就可以了查詢數據。另一方面,服務器需要保證從查詢開始到結束讀操作看到一個一致的數據視圖(即時其他用戶修改,數據看上去也要相同)。這個方法被稱為版本控制。
這兩種方法各有利弊,第一種方法在有較多的並行讀取請求和寫請求時等待時間過長;如果在修改數據時存在長期運行的查詢,則第二種方法也是有問題的。
在常用的數據庫服務器中,Microsoft SQL Server采取第一種方法,Oracle采取第二種方法,MySQL則兩種方法都包括(取決於使用者對存儲引擎的選擇)。
鎖的粒度
決定如何鎖定一個資源時也可以采用一些不同的策略。服務器可能在3個不同級別之一應用鎖,或者稱為粒度:
表鎖:阻止多用戶同時修改同一個表的數據。
頁鎖:阻止多用戶同時修改某表中同一頁(一頁通常是一段2~16KB的內存空間)的數據。
行鎖:阻止多用戶同時修改某表中同一行的數據。
同樣,這些方法各有利弊,表鎖需要較少的簿記就可以鎖定整個表,但是當用戶增多時它會迅速產生不可接受的等待時間。另一方面,行鎖需要更多的簿記,但是只要各個用戶的興趣在不同的行,它就能允許多人修改同一個表。
在常用的數據庫服務器中,Microsoft SQL Server使用表鎖、頁鎖和行鎖,Oracle只有行鎖,MySQL使用表鎖、頁鎖和行鎖(同樣取決於使用者對存儲引擎的選擇)。在某些情況下,SQL Server會將鎖從行鎖升級至頁鎖,再從頁鎖升級至表鎖。然而Oracle數據庫從不升級鎖。
