小白科普:悲觀鎖和樂觀鎖

轉自:碼農翻身(微信號:coderising)

一、無鎖
旺財和小強生活在一個網上商城的系統中, 是一對兒線程好基友。

星期一剛上班,旺財接到領導電話說,要把一個商品的庫存減小20, 旺財不敢怠慢,趕快把庫存取出來一看,哦,如今有1000個。

與此同時,小強也接到電話說要把同一商品的庫存減小30, 他一看,哦,如今有1000個。

旺財計算出最新的庫存值980, 保存!

小強也計算出最新的庫存值970, 保存 !  

旺財的數據被小強覆蓋了!

領導一看,原本賣出了50個商品,如今庫存只扣了30個,這樣持續下去就天下大亂了。

旺財和小強, 各打二十大板, 長長記性!

二、悲觀鎖
小強說:「哥,要不咱們仍是想個辦法吧,再這樣下去要被打死的。」

旺財悲催地說: 「這樣, 之後咱們每次訪問庫存以前,都要先加鎖,加了鎖,就禁止別人再進入訪問,只能等待持有鎖的人來釋放。」

星期二, 領導讓旺財再次把庫存減小20 , 旺財此次萬分當心,先把庫存給鎖住,而後慢慢修改。

小強也接到了把庫存減小的指令, 可是旺財哥已經把庫存鎖住了, 不能操做,小強只好去阻塞車間喝茶聊天,而後到就緒車間等待調度運行。

好不容易等到能夠再次執行了,小強一看,這庫存怎麼還鎖着呢!? 只好再次去阻塞車間喝茶。

領導一看, 小強你怎麼回事, 總是喝茶聊天? !  還幹不幹活了?

小強爭辯說旺財哥一直鎖着庫存,我無法操做。

領導無論這些, 把小強和旺財又打了二十大板。

(備註: 這種加鎖的方式就是悲觀鎖了,悲觀鎖正如其名,每次取讀寫數據時候總認爲數據會被別人修改,因此將數據加鎖,置於鎖定狀態, 不讓別人再訪問。缺點是若是持有鎖的時間太長,其餘用戶須要等待很長時間。)

三、樂觀鎖
旺財說: 「兄弟,這一次哥對不住你啊,處理得慢了一些, 不過哥剛纔捱打的時候想了一個好辦法:樂觀鎖。」

小強說:「拉倒吧你,屁股都快被打爛了還樂觀?」

「你聽我說嘛, 咱們在那個庫存字段的旁邊,再加上一個版本(version)的字段, 例如剛開始的時候(庫存= 1000, 版本=1), 每次你去讀的時候不只要讀出庫存,還要讀出版本號, 等到你修改了庫存,往回寫的時候必定要檢查一下版本號,看看和你讀的時候是否同樣。」

「若是不同呢?」  小強問

「那就放棄此次寫的操做,從新讀取庫存和版本號, 從新來過。」

「若是同樣呢? 」

「那就放心大膽地把新的庫存值寫回去。把版本號也加1」

「我彷佛有點明白了,咱們試試,不過你要想好,我可不想再挨板子了。」

星期三, 旺財奉命把庫存減去30, 他先讀到了(庫存= 1000, 版本=1);  小強也要改庫存了,他要把庫存減去50, 因而他也讀到了(庫存= 1000, 版本=1)。

旺財計算出新的庫存值970 ,寫回成功,如今版本變成了(庫存= 970, 版本=2)。

小強也計算出新庫存950 , 也準備寫回,他戰戰兢兢地去看最新的版本號, 已經變成版本2了, 按照以前的約定,只好從新讀取了。

小強再次讀取(庫存= 970, 版本=2) , 計算出最新緩存值920(970減去50), 再次試圖更新,沒想到又被別人搶了先,如今版本號已經變成3了,最新的數據是(庫存= 900, 版本= 3)。

唉, 只好從新來過, 計算出最新緩存值850(900減去50),第三次終於更新成功了, 最新的庫存是 (庫存=850, 版本= 4)

領導看到旺財和小強忙得熱火朝天,一刻不停,而且庫存值也沒有亂掉, 滿意地點了點頭:好同志啊。

(備註: 這種方式就是所謂的樂觀鎖了,旺財和小強此次樂觀了一點,以爲通常狀況下不會有太多人修改庫存,因此沒有加鎖,放心地去操做,只有在最後更新的時候纔去看是否衝突。 這種方式適合於衝突很少的場景,若是衝突不少,數據爭用激烈,會致使不斷地嘗試,反而下降了性能。)

四、成功案例

緩存

相關文章
相關標籤/搜索