<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    java技術(shù)研究

    統(tǒng)計

    留言簿(3)

    閱讀排行榜

    評論排行榜

    悲觀鎖與樂觀鎖(轉(zhuǎn))

    先申明概念:

    1、悲觀鎖,正如其名,它指的是對數(shù)據(jù)被外界(包括本系統(tǒng)當前的其他事務(wù),以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機制(也只有數(shù)據(jù)庫層提供的鎖機制才能真正保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實現(xiàn)了加鎖機制,也無法保證外部系統(tǒng)不會修改數(shù)據(jù))。
    2、樂觀鎖( Optimistic Locking )
    相對悲觀鎖而言,樂觀鎖機制采取了更加寬松的加鎖機制。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機制實現(xiàn),以保證操作最大程度的獨占性。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷,特別是對長事務(wù)而言,這樣的開銷往往無法承受。而樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基于數(shù)據(jù)版本( Version )記錄機制實現(xiàn)。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個版本標識,在基于數(shù)據(jù)庫表的版本解決方案中,一般是通過為數(shù)據(jù)庫表增加一個 “version” 字段來實現(xiàn)。讀取出數(shù)據(jù)時,將此版本號一同讀出,之后更新時,對此版本號加一。此時,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應(yīng)記錄的當前版本信息進行比對,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當前版本號,則予以更新,否則認為是過期數(shù)據(jù)。

    所以悲觀鎖和樂觀鎖最大的區(qū)別是是否一直鎖定資源,悲觀鎖在事物的全流程鎖定數(shù)據(jù),樂觀鎖不鎖定數(shù)據(jù)(用讀寫鎖是阻塞事物,而用樂觀鎖則會導(dǎo)致回滾。這個是一種事物沖突后的不同鎖的表象)。樂觀鎖的最大特點是在最后檢查數(shù)據(jù)是否被修改,如果已被別人修改過,則回滾數(shù)據(jù),避免臟數(shù)據(jù)。至于事物是否沖突和加鎖沒有直接聯(lián)系,該沖突的還是會沖突,不管你加悲觀鎖和樂觀鎖都會沖突。

    悲觀鎖和樂觀鎖都是為了解決丟失更新問題或者是臟讀。悲觀鎖和樂觀鎖的重點就是是否在讀取記錄的時候直接上鎖。悲觀鎖的缺點很明顯,需要一個持續(xù)的數(shù)據(jù)庫連接,這在web應(yīng)用中已經(jīng)不適合了。

    一個比較清楚的場景

    下面這個假設(shè)的實際場景可以比較清楚的幫助我們理解這個問題:

    a. 假設(shè)當當網(wǎng)上用戶下單買了本書,這時數(shù)據(jù)庫中有條訂單號為001的訂單,其中有個status字段是’有效’,表示該訂單是有效的;
    b. 后臺管理人員查詢到這條001的訂單,并且看到狀態(tài)是有效的
    c. 用戶發(fā)現(xiàn)下單的時候下錯了,于是撤銷訂單,假設(shè)運行這樣一條SQL: update order_table set status = ‘取消’ where order_id = 001;
    d. 后臺管理人員由于在b這步看到狀態(tài)有效的,這時,雖然用戶在c這步已經(jīng)撤銷了訂單,可是管理人員并未刷新界面,看到的訂單狀態(tài)還是有效的,于是點擊”發(fā)貨”按鈕,將該訂單發(fā)到物流部門,同時運行類似如下SQL,將訂單狀態(tài)改成已發(fā)貨:update order_table set status = ‘已發(fā)貨’ where order_id = 001

    觀點1:只有沖突非常嚴重的系統(tǒng)才需要悲觀鎖;
    分析:這是更準確的說法;
    “所有悲觀鎖的做法都適合于狀態(tài)被修改的概率比較高的情況,具體是否合適則需要根據(jù)實際情況判斷。”,表達的也是這個意思,不過說法不夠準確;的確,之所以用悲觀鎖就是因為兩個用戶更新同一條數(shù)據(jù)的概率高,也就是沖突比較嚴重的情況下,所以才用悲觀鎖。

    觀點2:最后提交前作一次select for update檢查,然后再提交update也是一種樂觀鎖的做法
    分析:這是更準確的說法;
    的確,這符合傳統(tǒng)樂觀鎖的做法,就是到最后再去檢查。但是wiki在解釋悲觀鎖的做法的時候,’It is not appropriate for use in web application development.’, 現(xiàn)在已經(jīng)很少有悲觀鎖的做法了,所以我自己將這種二次檢查的做法也歸為悲觀鎖的變種,因為這在所有樂觀鎖里面,做法和悲觀鎖是最接近的,都是先select for update,然后update

    *****除了上面的觀點1和觀點2是更準確的說法,下面的所有觀點都是錯誤的***********

    觀點3:這個問題的原因是因為數(shù)據(jù)庫隔離級別是uncommitted read級別;
    分析:這個觀點是錯誤的;
    這個過程本身就是在read committed隔離級別下發(fā)生的,從a到d每一步,尤其是d這步,并不是因為讀到了未提交的數(shù)據(jù),僅僅是因為用戶界面沒有刷新[事實上也不可能做自動刷新,這樣相當于數(shù)據(jù)庫一發(fā)生改變立刻要刷新了,這需要監(jiān)聽數(shù)據(jù)庫了,顯然這是簡單問題復(fù)雜化了];

    觀點4:悲觀鎖是指一個用戶在更新數(shù)據(jù)的時候,其他用戶不能讀取這條記錄;也就是update阻塞讀才叫悲觀鎖;
    分析:這個觀點是錯的;
    這在db2背景的開發(fā)中尤其常見;因為db2默認就是update會阻塞讀;但是這是各個數(shù)據(jù)庫對讀寫的時候上鎖的并發(fā)處理實現(xiàn)不一樣。但這根本不是悲觀鎖樂觀鎖的區(qū)別。Oracle可以做到寫不阻塞讀僅僅是因為做了多版本并發(fā)控制(Multiversion concurrency control), http://en.wikipedia.org/wiki/Multiversion_concurrency_control;但是在Oracle里面,一樣可以做樂觀鎖和悲觀鎖的控制。這本質(zhì)上是應(yīng)用層面的選擇。

    觀點5:Oracle實際上用的就是樂觀鎖
    分析:這個觀點是錯的;
    前面說了,Oracle的確可以做到寫不阻塞讀,但是這不是悲觀鎖和樂觀鎖的問題。這是因為實現(xiàn)了多版本并發(fā)控制。按照wiki的定義,悲觀鎖和樂觀鎖是在應(yīng)用層面選擇的。Oracle的應(yīng)用只要在第二步做了select for update,就是悲觀鎖的做法;況且Oracle在任何隔離級別下,除了分布式事務(wù)兩階段提交的短暫時間,其他所有情況下都不存在寫阻塞讀的情況,如果按照這個觀點的話那Oracle已經(jīng)不能做悲觀鎖了-_-

    觀點6:不需要這么麻煩,只需要在d這步,最后提交更新的時候再做一個普通的select檢查一下就可以;[就是double check的做法]
    分析:這個觀點是錯的。
    這個做法其實在http://www.hetaoblog.com/database-lost-update-pessimistic-lock/,’3. 傳統(tǒng)悲觀鎖做法的變通’這節(jié)已經(jīng)說明了,如果要這么做的話,仍然需要在最后提交更新前double check的時候做一個select for update, 否則select結(jié)束到update提交前的時間仍然有可能記錄被修改;

    觀點7:應(yīng)該盡可能使用悲觀鎖;
    分析:這個觀點是錯的;
    a. 根據(jù)悲觀鎖的概念,用戶在讀的時候(b這步)就會將記錄鎖住,直到更新結(jié)束的時候才會將鎖釋放,所以整個鎖的過程時間比較長;
    b. 另外,悲觀鎖需要有一個持續(xù)的數(shù)據(jù)庫連接,這在當今的web應(yīng)用中已經(jīng)幾乎不存在;wiki上也說了, 悲觀鎖‘is not appropriate for use in web application development.’

    所以,現(xiàn)在大部分應(yīng)用都應(yīng)該是樂觀鎖的;
    轉(zhuǎn)自:http://zhidao.baidu.com/link?url=MUOUg59oz7-FKwz-zuUviGryfw9J4V63Pd2iWWErorwUpyeL85rznlmYaGDHXjH_ChywA3R1m9XNpx4k7RCCT3rNofjkCxIBYHdsvwr2bVy

    posted on 2016-01-05 09:32 小秦 閱讀(334) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲AV永久精品爱情岛论坛| 亚洲欧洲精品无码AV| 亚洲国产精品久久网午夜| a国产成人免费视频| 亚洲综合伊人久久大杳蕉| eeuss草民免费| 国产成人A亚洲精V品无码| 男人j进入女人j内部免费网站| 亚洲成av人片天堂网| 三年片在线观看免费观看大全一| 久久久久亚洲AV成人无码网站| 可以免费观看的国产视频| 中文字幕在线观看亚洲| 99久久国产热无码精品免费| 亚洲成av人片在线看片| 国内一级一级毛片a免费| 亚洲av无码专区在线电影天堂| 亚洲av麻豆aⅴ无码电影| 精品久久久久久无码免费| 亚洲精品无码不卡| 国产一精品一AV一免费孕妇| 亚洲av无码专区在线电影天堂| 国产黄色一级毛片亚洲黄片大全| 毛片免费在线观看| 亚洲AV色吊丝无码| 亚洲国产精品无码久久久久久曰| 国产中文字幕在线免费观看 | 国产av无码专区亚洲av果冻传媒| 人妻免费一区二区三区最新| 亚洲激情电影在线| 国产一级一片免费播放i| 特级做A爰片毛片免费看无码 | 亚洲午夜爱爱香蕉片| 免费日本一区二区| 亚洲人成网站色7799| 亚洲日韩中文字幕日韩在线| 59pao成国产成视频永久免费| 久久亚洲AV成人无码国产电影| 亚洲av无码成h人动漫无遮挡| 免费无码黄十八禁网站在线观看 | 亚洲欧洲日产国码www|