一、定義
1.悲觀鎖:即很悲觀,每次拿數據的時候都覺得數據會被人更改,所以拿數據的時候就把這條記錄鎖掉,這樣別人就沒法改這條數據了,一直到你的鎖釋放。
2.樂觀鎖:即很樂觀,查詢數據的時候總覺得不會有人更改數據,等到更新的時候再判斷這個數據有沒有被人更改,有人更改了則本次更新失敗。
二、實現過程
2.悲觀鎖:悲觀鎖的實現采用的數據庫內部的鎖機制,一個典型的倚賴數據庫的悲觀鎖調用:
select * from account where name=”張三” for update
這條sql 語句鎖定了account 表中所有符合檢索條件(name=”Erica”)的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。也就是我們可以在查詢數據的時候先用for update把這條數據鎖住,然后更改完這條數據再提交。這樣別的線程沒法更新這條數據,也就保證了不會丟失更新。
2.1.悲觀鎖帶來的性能問題。我們試想一個場景:如一個金融系統,當某個操作員讀取用戶的數據,並在讀出的用戶數據的基礎上進行修改時(如更改用戶帳戶余額),如果采用悲觀鎖機制,也就意味着整個操作過程中(從操作員讀出數據、開始修改直至提交修改結果的全過程),數據庫記錄始終處於加鎖狀態,可以想見,如果面對幾百上千個並發,這樣的情況將導致怎樣的后果?所以我們這個時候可以使用樂觀鎖。
1.樂觀鎖:樂觀鎖的實現可以通過在表里面加一個版本號的形式,下面是一個實例。
講解:也就是每個人更新的時候都會判斷當前的版本號是否跟我查詢出來得到的版本號是否一致,不一致就更新失敗,一致就更新這條記錄並更改版本號。
二、使用場景
像樂觀鎖適用於寫比較少的情況下,即沖突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生沖突,
上層應用會不斷的進行retry,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適