在創作該文當天下午,看見某篇秒殺技術部落格的文章說道利用mysql樂觀鎖提高併發(原文如下)
悲觀鎖雖然可以解決超賣問題,但是加鎖的時間可能會很長,
會長時間的限制其他使用者的訪問,導致很多請求等待鎖,
卡死在這裡,如果這種請求很多就會耗盡連線,系統出現異常。
樂觀鎖預設不加鎖,更失敗就直接返回搶購失敗,可以承受較高併發
突然發下自己對mysql樂觀鎖概念很是模糊,隱約知道有這個概念,便去網上搜尋學習,然而在學習過程基本看到的都是:
樂觀鎖:
新增欄位version或者類似字段
更新語句:update table1 set a=1, version = version + 1 where id = 2 and version = version // 1
悲觀鎖 更新語句:update table1 set a=1, version = version + 1 where id = 2 // 2
在看到這種解釋和樂觀鎖實現方式後,認知觀崩塌了。原因有2:
1. 都是mysql資料庫,使用的都是innodb引擎,都是update語句使用排他鎖(for update),憑啥多了and version = version
就叫樂觀鎖?
2. 難道上面兩條語句的效果不是一樣?當語句1執行時開啟事務,在事務提交之前其它事務只能阻塞,事務提交後其他事務拿到最新view重新加鎖,此時的version = version有起到作用?
於是乎,我便思索再三,自己給了份解釋給自己!
首先,這種解釋下mysql的樂觀鎖本質還是悲觀鎖,因為update語句mysql預設都是排他鎖,典型的悲觀鎖。
其次,這種解釋下mysql的樂觀鎖只能說是一種思想或者境界,反正挺玄乎的乙個東西,並不是大家傳統觀念中的樂觀鎖cas這種。
最後,這種解釋下mysql的樂觀鎖的update語句應該是update table1 set a=1, version = version + 1 where id = 2 and version = #
,某種意義上的確是可以提高併發能力。比如,mysql併發量較大,假設5000個連線需要去執行這條語句,就像小蝌蚪奔向終點形成受精軟一樣,一定會有乙個幸運兒(連線)首先開啟事務,執行update,其他4999個連線都阻塞等待幸運兒提交事務,這個時候就不會滿足where id = 2 and version = #
條件而執行失敗。否則的話剩餘的4999個連線會重新競爭資源加鎖,直到服務***,被老闆開除,世界末日
ps: 上述栗子並不是很恰當,所以不要質疑誰會開啟5000個mysql連線,為什麼會世界末日。
實現真正意義上的合併排序
演算法老師布置這道題好長時間了,可是一直沒有思路,真的是憋出來的 啊 真正意義上的合併排序是按照給的陣列來判斷的,它分的不是兩兩一組,在四四一組排序,直到完全排完序,真正意義上的合併排序是指 先在陣列上找到已有序的陣列,分成幾塊,在進行合併。如下 include define n 10 define...
哪些網域名稱才是真正意義上的好網域名稱?
首先網域名稱是網際網路的門牌號,乙個好的網域名稱,就像是有乙個好地段的房產權一樣,乙個好網域名稱也是你的 成功的基石。但是如何才能識別出哪些是好網域名稱?下面先和大家談談什麼型別的網域名稱才是好網域名稱。1 com是 王道 儘管現在很多地方都會告訴你.com如何如何資源貧乏,com仍舊是 王道 而且...
c 中的const為真正意義上的const
define crt secure no warnings include include include int main include using namespace std c 中的const為真正意義上的const 由於符號表機制 c 編譯器對const常量的處理 編譯過程中若發現使用常量...