數據庫鎖:樂觀鎖分佈式高併發最佳應用舉例「開發面試必備」

數據庫鎖:樂觀鎖分佈式高併發最佳應用舉例「開發面試必備」

背景

多人併發操作同一數據,可能導致數據不一致,數據不一致可是非常可怕的bug。

這是接上篇悲觀鎖講解,

樂觀悲觀鎖區別

  1. 併發衝突概率大的走悲觀鎖合適,概率小的走樂觀鎖
  2. 數據庫開銷不一樣,悲觀佔用資源多特別是長事務的情況,影響了程序的併發訪問性,樂觀鎖相反。

業務場景

工作流業務,如員工A操作工單審批通過,同時員工B也操作了相同的工單審批拒絕,

此時這個工單狀態字段可能出現不一致情況。

問題來了

  1. 當應用的用戶量上來了,就像今日頭條從剛開始的幾萬,到如今上億的用戶量,APP操作的響應時間越來越慢,然後老闆發話了,必須提高響應時間,讓APP操作能毫秒級響應。
  2. 程序汪,接到命令就開始分析代碼,發現mysql的select x for udpate 鎖,有時佔有數據庫資源非常大。提供數據庫的響應速度可是優化性能的殺手鐧啊。

解決思路

  1. 程序汪說幹就幹,在業務單表裡加了個lock_version字段 int類型,默認0, 0:未鎖 1:鎖住
  2. 先 select version from 業務單 where id=x ;
  3. 獲得 version的值0,如果是1,表示已經被其他人鎖了,直接退出操作或異常提示

偽代碼走起

事務 begin------

相應的業務邏輯.......

【update 業務表 set 業務值, version=version+1 where id=#{id} and version=#{version};如果更新數據影響1行,返回true 否則返回false】

更新影響1行success【加鎖OK】 ,lock_version_boolean=true 否則false【加鎖失敗】

if(!lock_version_boolean){

throw new Exception("親,你併發異常了")

}

事務 end------

finally{

最後把鎖重置 為update 0:未鎖 狀態【鎖釋放】

}

找了張圖,大家理解下

數據庫鎖:樂觀鎖分佈式高併發最佳應用舉例「開發面試必備」

version控制

注意

  1. 樂觀鎖思想在SVN,GIT就得到了應用,下載代表有version,提交代碼是會更新version,當發現version不一致就提交失敗。
  2. 在併發量不是很大情況for update完全夠用,代碼夠簡單。悲觀鎖代碼稍微複雜點點,請根據場景正確選擇。
  3. 樂觀鎖說白了就一個update的sql,請注意version參數別傳錯了,添加version字段到你核心業務表中,如電影系統內容表就是核心表。

如果覺得對你有幫助請關注,有錯誤請指點,下篇繼續分析 【高性能緩存鎖】

數據庫鎖:樂觀鎖分佈式高併發最佳應用舉例「開發面試必備」

數據庫鎖:樂觀鎖分佈式高併發最佳應用舉例「開發面試必備」


分享到:


相關文章: