更新於 2024/10/13閱讀時間約 3 分鐘

資料庫系列 - 4: DB Lock

這一周我們來介紹一個稍微簡單的概念—資料庫鎖(DB lock)。

介紹 & 概念

試想一下,當你和其他人同時對一張資料表進行操作時,要怎麼讓資料庫知道要保留誰的儲存?特別是當操作涉及到同一筆資料時,如何確保資料的一致性和完整性?此時最直觀的方式就是起來!當一個人正在對資料表進行修改時,資料庫會對該資料表或該筆資料加鎖,直到該用戶的操作完成並釋放鎖,而其他人在這段時間內不能對該資料進行修改。當第一個人完成操作並釋放鎖後,下一個用戶才能獲得鎖並進行操作。這樣便可以防止資料競爭和不一致的情況發生。

因此我們可以很簡單的理解到,DB lock 的本質就是防止多個請求同時對同一張表進行訪問,無論是讀取還是寫入。通過適當的鎖定機制,資料庫可以確保資料的完整性和一致性,並提高系統的穩定性和可靠性。

鎖的類型

  • 排他鎖(Exclusive Lock): 又稱為「寫鎖」,其他請求無法讀取或寫入。
  • 共享鎖(Shared Lock): 又稱為「讀鎖」,其他請求可以讀取、無法寫入。
  • 意向鎖(Intention Lock): 用來協調不同層次的鎖。
  • 自動鎖(Implicit Lock): 由資料庫系統自動管理,通常會自動獲得和釋放。
  • 顯式鎖(Explicit Lock): 由請求或應用程式顯式請求和釋放,通常使用SQL語句(如 LOCK TABLE)來操作。
  • 行鎖定(Row Lock):這是一種細粒度的鎖定,用於鎖定資料表中的特定行,因此可以提高併發時的性能。
  • 表鎖定(Table Lock):這是一種粗粒度的鎖定,用於鎖定整個資料表,會降低併發時的性能。

鎖的優點

優點應該很明顯,就是我前面有提到的保持數據一致性與完整性~

鎖的缺點之一 — 鎖競爭

鎖競爭是指當多個請求同時嘗試訪問相同資源時,因為鎖的存在而出現的資源競爭現象。這種情況會導致等待操作被延遲,進而影響整體的執行效率。

造成鎖競爭的原因主要有以下四種:

  • 高併發:當系統同時接收大量請求時,會導致處理能力不足,從而引發鎖競爭。大量請求需要爭奪有限的鎖資源,導致等待時間增加。
  • 不當的鎖粒度:如果鎖的粒度過大,例如在只需要修改單條資料的情況下使用了表鎖而非行級鎖,就會造成不必要的競爭。合適的鎖粒度應該根據實際需求來選擇,以最小化鎖的範圍。
  • 長時間持有鎖:某些操作可能需要較長時間來完成,這會長時間佔據鎖資源。長時間持有鎖會導致其他請求的等待時間增加,甚至可能引發死鎖。
  • 不必要的鎖:有些操作實際上不需要加鎖。例如,某些讀取操作可能不會改變數據狀態,此時加鎖可能會引起不必要的鎖競爭。

鎖的缺點之二 — 鎖等待與死鎖

所謂的鎖等待,就是在一個請求持有某個鎖時,若它需要另一個鎖,則會進入等待狀態,直到該鎖被釋放。而所謂的死鎖,就是指兩個或多個請求互相握有對方所需要的鎖,導致每個請求都無法進一步執行,最終使得整個系統處於卡住的狀態。

舉例來說,假設有兩個請求:

  • 請求A:正在處理資料表A,擁有A鎖,待會需要處理資料表B。
  • 請求B:正在處理資料表B,擁有B鎖,待會需要處理資料表A。

在這種情況下,請求A需要等待請求B釋放資料表B的鎖,而請求B則需要等待請求A釋放資料表A的鎖。因為兩個請求都在等待對方釋放鎖,導致彼此無法繼續進行下去,形成了死鎖。

**需要特別注意的是,**死鎖不僅僅是由兩個請求引起的,它也可能涉及三個或更多的請求,每個請求都持有其他請求所需的鎖。這種情況下,整個系統可能會陷入更複雜的死鎖狀態。

希望閱讀完這篇文章的你可以對資料庫所有更深的了解喔~

參考資料

  1. https://www.mysql.tw/2023/05/mysql-lock.html#google_vignette
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.