国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

php - 高并發(fā)下悲觀鎖與樂觀鎖的選擇問題
ringa_lee
ringa_lee 2017-05-16 13:05:01
0
4
961

說說我的看法,不對的地方請指正。

樂觀鎖的實現(xiàn)原理是cas操作,java中輕量級鎖也是基于cas實現(xiàn)的。

悲觀鎖最大的問題就是阻塞問題。

在深入理解java虛擬機中提到,輕量級鎖一般情況下是優(yōu)于重量級鎖(互斥鎖)的;如果在高并發(fā)鎖競爭比較激烈的情況下輕量級鎖會由于長時間自旋消耗cpu 從而使得輕量級鎖的性能比傳統(tǒng)的重量級鎖更慢。那么樂觀鎖中也有自旋和cas,所以高并發(fā)下樂觀鎖好像不是一種好的解決方案。

但是有些博文中提到 高并發(fā)下使用樂觀鎖更合適
比如這篇文章中就提到高并發(fā)數(shù)據(jù)庫訪問使用樂觀鎖
http://blog.csdn.net/amqvje/a...

問題1,高并發(fā)下如何選擇?

問題2 樂觀鎖有什么缺點? 為什不都使用樂觀鎖。高并發(fā)下都是使用樂觀鎖,如果并發(fā)量不高,使用樂觀鎖感覺更不是問題

ringa_lee
ringa_lee

ringa_lee

全部回復(fù)(4)
劉奇

簡單的來說,一般情況下,樂觀鎖適合只有讀沒有寫的操作,悲觀鎖適合于讀寫混合的操作。如果寫操作非常簡單短小,比如增加訪問人數(shù),也可以用樂觀鎖,或者不需要確保讀到的數(shù)據(jù)是最新的時候。80%的情況下使用樂觀鎖確實是比較好的選擇。

CAS依靠硬件CPU指令支持去實現(xiàn)原子級操作,所以高并發(fā)的情況下一般會更快,但是這個快不是沒有缺點的,缺點就是有讀也有寫的時候,CPU緩存失效率可能會增加,除非你的CPU是單核的(非Intel平臺的嵌入式)。

總而言之,要提升高并發(fā)性能,還是要實際測量出的數(shù)據(jù)說明問題,我上面提到的都是理論。希望對你有幫助。

阿神

無論是悲觀鎖還是樂觀鎖,其實都是并發(fā)控制的一種思想,并不僅僅局限于數(shù)據(jù)庫,具體如何選擇樂觀鎖和悲觀鎖是根據(jù)業(yè)務(wù)場景來的。
悲觀鎖:
一般情況下,我們使用的悲觀鎖就是在數(shù)據(jù)庫層面增加一個排它鎖,加鎖成功就可以修改數(shù)據(jù)然后提交事務(wù),事務(wù)提交成功解鎖,失敗就說明數(shù)據(jù)正在被修改。如果你使用mysql的innodb的話,要注意 set autocommit=0關(guān)閉mysql自動提交屬性,因為mysql默認(rèn)使用autocommit模式,就是說,當(dāng)你執(zhí)行一個更新操作后,MySQL會立刻將結(jié)果進行提交,另外還要注意鎖的級別,默認(rèn)innodb是使用行級鎖,但是行級鎖是基于索引的,如果你這條sql沒用索引,那么mysql就會使用表級鎖鎖表了。
優(yōu)缺點:
悲觀鎖是“先取鎖再訪問”的保守策略,為數(shù)據(jù)處理的安全提供了保證。但是在效率方面,處理加鎖的機制會讓數(shù)據(jù)庫產(chǎn)生額外的開銷,還有增加產(chǎn)生死鎖的機會。另外,在只讀型事務(wù)處理中由于不會產(chǎn)生沖突,也沒必要使用鎖,這樣做只能增加系統(tǒng)負(fù)載。還有會降低了并行性,一個事務(wù)如果鎖定了某行數(shù)據(jù),其他事務(wù)就必須等待該事務(wù)處理完才可以處理那行數(shù)據(jù)。

樂觀鎖:
樂觀鎖其實就是假設(shè)認(rèn)為數(shù)據(jù)一般情況下不會造成沖突,所以在數(shù)據(jù)進行提交更新的時候,才會正式對數(shù)據(jù)的沖突與否進行檢測,如果發(fā)現(xiàn)沖突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。
一般直接寫在代碼邏輯層就可以了,相對于悲觀鎖,在對數(shù)據(jù)庫進行處理的時候,樂觀鎖并不會使用數(shù)據(jù)庫提供的鎖機制,通常采用一個version版本號或時間戳來實現(xiàn)。使用版本號時,可以在數(shù)據(jù)初始化時指定一個版本號,每次對數(shù)據(jù)的更新操作都對版本號執(zhí)行+1操作。并判斷當(dāng)前版本號是不是該數(shù)據(jù)的最新的版本號。如:

1.查詢出商品信息
select (status,version) from t_goods where id=#{id}
2.根據(jù)商品信息生成訂單
3.修改商品status為2
update t_goods 
set status=2,version=version+1
where id=#{id} and version=#{version};

優(yōu)缺點:
樂觀鎖認(rèn)為數(shù)據(jù)競爭的概率是很小的,因此,盡可能直接做下去,直到提交的時候才去鎖定,所以不會產(chǎn)生任何鎖和死鎖。但如果直接簡單這么做,還是有可能會遇到不可預(yù)期的結(jié)果,例如兩個事務(wù)都讀取了數(shù)據(jù)庫的某一行,經(jīng)過修改以后寫回數(shù)據(jù)庫,這時就遇到了問題。
樂觀鎖存在失效的情況,屬小概率事件,需要多個條件共同配合才會出現(xiàn)。如:

  • 應(yīng)用采用自己的策略管理主鍵ID。如,常見的取當(dāng)前ID字段的最大值+1作為新ID。

  • 版本號字段 version 默認(rèn)值為 0 。

  • 用戶A讀取了某個記錄準(zhǔn)備修改它。該記錄正好是ID最大的記錄,且之前沒被修改過,version 為默認(rèn)值 0。

  • 在用戶A讀取完成后,用戶B恰好刪除了該記錄。之后,用戶C又插入了一個新記錄。

  • 此時,陰差陽錯的,新插入的記錄的ID與用戶A讀取的記錄的ID是一致的, 而版本號兩者又都是默認(rèn)值 0。

  • 用戶A在用戶C操作完成后,修改完成記錄并保存。由于ID、version均可以匹配上,因此用戶A成功保存。但是,卻把用戶C插入的記錄覆蓋掉了。
    樂觀鎖此時的失效,根本原因在于應(yīng)用所使用的主鍵ID管理策略, 正好與樂觀鎖存在極小程度上的不兼容。

PHPzhong

沒工作之前我也是和題主相同的想法,實際工作中,其實兩者差別不大,真正高并發(fā)下系統(tǒng)耗時的地方永遠(yuǎn)是網(wǎng)絡(luò)連接,數(shù)據(jù)庫查詢以及線程的主動睡眠,鎖帶來開銷基本可以忽略不計

我想大聲告訴你

關(guān)鍵問題在于,事實是悲觀的還是樂觀的?

假如你的資源競爭很激烈,并且無法共享的話,樂觀鎖不過是讓大量請求的希望落空罷了。

假如你的資源沒什么競爭(這個和并發(fā)高低沒必然的關(guān)聯(lián),業(yè)務(wù)的影響更大),那悲觀鎖意味著不必要地加鎖。如果原本是可共享的資源(比如資源支持多個只讀方),那么悲觀鎖意味著失去原本的可以使用的時間。

在深入理解java虛擬機中提到,輕量級鎖一般情況下是優(yōu)于重量級鎖(互斥鎖)的;如果在高并發(fā)鎖競爭比較激烈的情況下輕量級鎖會由于長時間自旋消耗cpu 從而使得輕量級鎖的性能比傳統(tǒng)的重量級鎖更慢。那么樂觀鎖中也有自旋和cas,所以高并發(fā)下悲觀鎖好像不是一種好的解決方案。

我并不了解 JVM。不過「樂觀鎖中也有自旋和cas」是什么意思?cas 就是自旋鎖的一種實現(xiàn)方式,為什么要并列呢?「也」是什么意思?悲觀鎖是個阻塞操作,沒有自旋,也不會持續(xù)消耗 CPU 的。

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板