Navicat 部落格

關聯式資料庫交易中的物件鎖定 2021 年 6 月 8 日,由 Robert Gravelle 撰寫

第 1 部分:概覽、鎖定資料粒度和死結

最近,我們有一些關於資料庫交易的文章,有關強制執行四個 ACID 特性(原子性、一致性、隔離性、持久性)。在今天的文章中,我們將研究關聯式資料庫(RDBMS)用於強制 ACID 特性的另一種機制,即物件鎖定。具體來說,我們將了解它是什麼,它在 RDBMS 交易中扮演什麼角色,以及鎖定可能造成的一些副作用。雖然資料庫物件鎖定可能是一個相當技術性和複雜的題目,但我們會以淺白的用語解釋它,並盡可能保持簡單易明。

什麼是物件鎖定?

簡單地說,物件鎖定是一種防止同時存取資料庫中資料的方法,以避免資料不一致。為了說明物件鎖定是如何運作的,假設兩個銀行出納員試圖為兩筆不同的交易更新同一個銀行帳戶。兩個出納員都擷取(即複製)帳戶記錄。出納員 A 申請並儲存一筆交易。出納員 B 對自己儲存的副本申請一筆不同的交易,並儲存結果,這筆交易會覆寫出納員 A 輸入的交易。現在,記錄不再反映第一筆交易,好像它從未發生過似的!

解決方法是在任何使用者修改記錄時鎖定該記錄,使其他使用者不能同時修改它。這樣可以防止記錄被錯誤地覆寫,但一次只允許處理一筆記錄,從而鎖定需要在同一執行個體中編輯記錄的其他使用者。因此,任何試圖擷取同一筆記錄進行編輯的人都會因為鎖定而被拒絕寫入存取(視乎具體的實施情況,他們可能仍然能够以唯讀狀態檢視該記錄)。一旦記錄被儲存(或取消編輯),鎖定就會被釋放。透過防止儲存記錄時覆蓋其他變更,資料完整性(ACID 中的 I)就得以保持。

鎖定資料粒度

上面的範例示範了一個記錄層級鎖定的事例。現在想像一下,如果上面的兩個銀行出納員為兩個不同的客戶提供服務,但他們的兩個帳戶都在同一個總帳中。在這種情況下,需要鎖定整個總帳(或一個或多個資料庫資料表)進行編輯。可以想像,鎖定整個資料表會導致大量不必要的等待。如果出納員可以從總帳中移除一分頁,其中包含目前客戶的帳戶(可能還包括一些其他帳戶),那麼可以同時為多個客戶提供服務,前提是每個客戶的帳戶位於不同的分頁上。如果兩個客戶在同一分頁上都有帳戶,則一次只能為一個客戶提供服務。這類似於資料庫中的分頁層級鎖定。

鎖定有四種類型。它們的資料粒度越來越細:

  • 資料庫鎖定
  • 資料表鎖定
  • 分頁鎖定
  • 列鎖定

鎖定資料粒度和死結

資料粒度鎖定的使用可能產生了一種稱為「死結」的情况。當使用遞增鎖定(鎖定一個實體,然後鎖定一個或多個額外的實體)時,可能會發生死結。舉例來說,我和妻子經常在我們的個人帳戶之間轉帳。如果我們每個人都要求出納員取得我們的個人帳戶資訊,這樣我們就可以把一些錢轉到對方的帳戶中,這兩個帳戶基本上就會被鎖定。然後,當我們的出納員試圖把錢轉到對方的帳戶時,他們會發現對方的帳戶「正在使用」,迫使他們等待帳戶釋放。不知不覺中,兩個出納員在等待對方,在對方放棄並退回帳戶之前,他們都無法完成交易!幸好有人已經設計出各種技術來避免這些問題。我們將在下一篇文章討論這些技術。

預告

在今天的文章中,我們知道了什麼是關聯式資料庫的物件鎖定、不同類型的鎖定和死結。在下一篇文章中,我們將談談一些衝突解决策略,以及封閉式與開放式鎖定。



Rob Gravelle 居住於加拿大渥太華,是一名有 20 多年經驗的 IT 專家。過住,Rob 曾為情報相關的組織(如加拿大邊境服務局和各種商業組織)建置系統。在業餘時間,Rob 是一名出色的吉他演奏家,並擁有多張 CD和數位發行

Navicat 文章
頻道記錄
分享
部落格封存檔