樂觀鎖 悲觀鎖

常見的鎖可以分成悲觀鎖跟樂觀鎖

悲觀鎖是認為同時修改資料的人很多,該特定資料被同時修改的機率比較大,因此會給資料加上一把鎖,只有先拿到鎖的人才有資格去修改資料,其餘的人只能排隊等待,直到第一個人修改完資料才有資格去修改資料

而樂觀鎖則是認為大部分時候同時修改資料的人不多,甚至只有一個人,因此該特定資料同時被修改的機率不高,所以很多人可以同時修改資料,但是只有第一個人的修改會被接受,其他人的修改都會被拒絕,只能重新跑一次修改資料的流程

悲觀鎖

悲觀鎖,Pessimistic Concurrency Control (PCC)

常見的悲觀鎖像是資料庫的 lock,或者是 排他鎖 mutex

優點

  • 因為是先拿鎖,再修改資料,因此資料正確性比較有保障
  • 通常我們能夠過資料庫來使用悲觀鎖,實作比較不容易出錯
  • 資料庫級別的鎖也能確保資料不被認知外的應用程式改到

缺點

  • 因為會需要處理加鎖機制,所以會產生額外開銷,效能比樂觀鎖差
  • 有機率產生死鎖

樂觀鎖,Optimistic Concurrency Control (OCC)

常見的樂觀鎖像是 CAS (Compare and Swap) ,透過 CPU 層級的指令來做到 CAS

優點

  • 沒有實際上鎖,所以效能比較好

缺點

  • 需要自己實作,確保邏輯的正確性
  • 如果同時修改數量很多,會失敗並重試很多次,比較消耗 CPU 資源
  • ABA 問題,1 2 同時拿到 A 狀態,1 把狀態改成 B,這時候 3 把狀態改回 A,2 會以為狀態沒改過,因此會修改資料,但實際上資料已經不是 2 當時拿的資料了
    • ⇒ 解法,加上 遞增版本號或時間戳,確保不會被改回 A

優化技巧

  • 縮小樂觀鎖的範圍
    • 樂觀鎖如果是要對數字做加減的話可以使用 DB 的增加/減少功能,並檢查做完後的條件是否符合條件,例如

參考資料


comments powered by Disqus