樂觀鎖 悲觀鎖
常見的鎖可以分成悲觀鎖跟樂觀鎖
悲觀鎖是認為同時修改資料的人很多,該特定資料被同時修改的機率比較大,因此會給資料加上一把鎖,只有先拿到鎖的人才有資格去修改資料,其餘的人只能排隊等待,直到第一個人修改完資料才有資格去修改資料
而樂觀鎖則是認為大部分時候同時修改資料的人不多,甚至只有一個人,因此該特定資料同時被修改的機率不高,所以很多人可以同時修改資料,但是只有第一個人的修改會被接受,其他人的修改都會被拒絕,只能重新跑一次修改資料的流程
悲觀鎖
悲觀鎖,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 的增加/減少功能,並檢查做完後的條件是否符合條件,例如