樂觀鎖與悲觀鎖各自適用場景是什麼?

機制

  1. 樂觀鎖是一種思想,具體實現是,表中有一個版本字段,第一次讀的時候,獲取到這個字段。處理完業務邏輯開始更新的時候,需要再次查看該字段的值是否和第一次的一樣。如果一樣更新,反之拒絕。之所以叫樂觀,因爲這個模式沒有從數據庫加鎖。

  2. 悲觀鎖是數據庫層面加鎖,都會阻塞去等待鎖。樂觀鎖優點程序實現,不會存在死鎖等問題。他的適用場景也相對樂觀。阻止不了除了程序之外的數據庫操作。悲觀鎖是數據庫實現,他阻止數據庫寫操作。再來說更新數據丟失,所有的讀鎖都是爲了保持數據一致性。樂觀鎖如果有人在你之前更新了,你的更新應當是被拒絕的,可以讓用戶從新操作。悲觀鎖則會等待前一個更新完成。這也是區別。具體業務具體分析

實現方式

樂觀鎖,version 方式:一般是在數據表中加上一個數據版本號 version 字段,表示數據被修改的次數,當數據被修改時,version 值會加一。當線程 A 要更新數據值時,在讀取數據的同時也會讀取 version 值,在提交更新時,若剛纔讀取到的 version 值爲當前數據庫中的 version 值相等時才更新,否則重試更新操作,直到更新成功。sql 實現代碼:

update table 
set x=x+1, version=version+1 
where id=#{id} and version=#{version};
  CAS操作方式:即compare and swap 或者 compare and set,

涉及到三個操作數,數據所在的內存值,預期值,新值。當需要更新時,判斷當前內存值與之前 取到的值是否相等,若相等,則用新值更新,若失敗則重試,一般情況下是一個自旋操作,即不 斷的重試。

悲觀鎖,是由數據庫自己實現的,要用的時候,我們直接調用數據庫的相關語句就可以了(原理:共享資源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程),如行鎖、讀鎖和寫鎖等,都是在操作之前加鎖。

使用場景

樂觀鎖:比較適合讀取操作比較頻繁的場景,如果出現大量的寫入操作,數據發生衝突的可能性就會增大,爲了保證數據的一致性,應用層需要不斷的重新獲取數據,這樣會增加大量的查詢操作,降低了系統的吞吐量。

悲觀鎖:比較適合寫入操作比較頻繁的場景,如果出現大量的讀取操作,每次讀取的時候都會進行加鎖,這樣會增加大量的鎖的開銷,降低了系統的吞吐量。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/2aWhO8emsNWG1f9v1XHhkQ