理解樂觀鎖和悲觀鎖

BookerABC發表於2024-11-09

樂觀鎖:認為每次去拿資料的時候別人不會修改,所以不會上鎖,但是每次要拿資料的時候都會先判斷資料是否被別人修改

悲觀鎖:認為每次去拿資料的時候別人都會修改,所以每次都會上鎖。

使用場景:樂觀鎖使用於多讀少寫的應用型別,這樣可以提高吞吐量;相反的情況則使用悲觀鎖

樂觀鎖和悲觀鎖是併發控制中兩種常見的鎖機制,它們分別基於不同的假設來處理資料的併發訪問。

樂觀鎖

實現
  1. 版本號機制:在資料表中增加一個版本號欄位,每次更新資料時,版本號加1。更新前檢查版本號是否發生變化,如果發生變化則更新失敗。
UPDATE table SET value = ?, version = version + 1 WHERE id = ? AND version = ?
  1. 時間戳機制:在資料表中增加一個時間戳欄位,每次更新資料時,時間戳更新為當前時間。更新前檢查時間戳是否發生變化,如果發生變化則更新失敗。
UPDATE table SET value = ?, timestamp = CURRENT_TIMESTAMP WHERE id = ? AND timestamp = ?
場景
  • 多讀少寫:適用於讀多寫少的場景,因為樂觀鎖在讀取資料時不加鎖,可以提高讀取的吞吐量。
  • 低併發:適用於併發衝突較少的場景,因為樂觀鎖在更新資料時需要檢查資料是否被修改,如果衝突頻繁,可能會導致大量重試。

悲觀鎖

實現
  1. 資料庫鎖:使用資料庫的鎖機制,如​​SELECT ... FOR UPDATE​​。
SELECT * FROM table WHERE id = ? FOR UPDATE
  1. 程式語言級別的鎖:使用程式語言提供的鎖機制,如Java中的​​synchronized​​關鍵字或​​ReentrantLock​​。
synchronized (lockObject) {
  
}
場景
  • 多寫少讀:適用於寫多讀少的場景,因為悲觀鎖在讀取資料時就加鎖,可以確保資料的一致性。
  • 高併發:適用於併發衝突較多的場景,因為悲觀鎖在讀取資料時就加鎖,可以避免頻繁的更新衝突。

相關文章