本篇內容主要講解“什么是樂觀鎖、悲觀鎖和MVCC”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“什么是樂觀鎖、悲觀鎖和MVCC”吧!
成都創(chuàng)新互聯(lián)公司網站建設公司是一家服務多年做網站建設策劃設計制作的公司,為廣大用戶提供了網站設計制作、成都網站制作,成都網站設計,廣告投放,成都做網站選成都創(chuàng)新互聯(lián)公司,貼合企業(yè)需求,高性價比,滿足客戶不同層次的需求一站式服務歡迎致電。
在數(shù)據(jù)庫的實際使用過程中,我們常常會遇到不希望數(shù)據(jù)被同時寫或者讀的情景,例如秒殺場景下,兩個請求同時讀到系統(tǒng)還有庫存1個,然后又先后把庫存更新為0,這時候就會出現(xiàn)超賣的情況,這時候貨物的實際庫存和我們的記錄就會對應不上了。
為了解決這種資源競爭導致的數(shù)據(jù)不一致等問題,我們需要有一種機制來進行保證數(shù)據(jù)的正確訪問和修改,而在數(shù)據(jù)庫中,這種機制就是數(shù)據(jù)庫的并發(fā)控制。其中樂觀并發(fā)控制,悲觀并發(fā)控制和多版本并發(fā)控制是數(shù)據(jù)庫并發(fā)控制主要采用的技術手段。
悲觀并發(fā)控制
一、本質
維基百科:在關系數(shù)據(jù)庫管理系統(tǒng)里,悲觀并發(fā)控制(又名“悲觀鎖”,PessimisticConcurrency Control,縮寫“PCC”)是一種并發(fā)控制的方法。它可以阻止一個事務以影響其他用戶的方式來修改數(shù)據(jù)。如果一個事務執(zhí)行的操作讀某行數(shù)據(jù)應用了鎖,那只有當這個事務把鎖釋放,其他事務才能夠執(zhí)行與該鎖沖突的操作。
事實上我們常說的悲觀鎖并不是一種實際的鎖,而是一種并發(fā)控制的思想,悲觀并發(fā)控制對于數(shù)據(jù)被修改持悲觀的態(tài)度,認為數(shù)據(jù)被外界訪問時,必然會產生沖突,所以在數(shù)據(jù)處理的過程中都采用加鎖的方式來保證對資源的獨占。
數(shù)據(jù)庫的鎖機制其實都是基于悲觀并發(fā)控制的觀點進行實現(xiàn)的,而且按照實際使用情況,數(shù)據(jù)庫的鎖又可以分為許多種類,具體可以見我后面的文章。
二、實現(xiàn)方式
數(shù)據(jù)庫悲觀鎖的加鎖流程大致如下:
開始事務后,按照操作類型給需要加鎖的數(shù)據(jù)申請加某一類鎖:例如共享行鎖等
加鎖成功則繼續(xù)后面的操作,如果數(shù)據(jù)已經被加了其他的鎖,而且和現(xiàn)在要加的鎖沖突,則會加鎖失?。ɡ缫呀浖恿伺潘i),此時需等待其他的鎖釋放(可能出現(xiàn)死鎖)
完成事務后釋放所加的鎖
三、優(yōu)缺點
優(yōu)點:
悲觀并發(fā)控制采取的是保守策略:“先取鎖,成功了才訪問數(shù)據(jù)”,這保證了數(shù)據(jù)獲取和修改都是有序進行的,因此適合在寫多讀少的環(huán)境中使用。當然使用悲觀鎖無法維持非常高的性能,但是在樂觀鎖也無法提供更好的性能前提下,悲觀鎖卻可以做到保證數(shù)據(jù)的安全性。
缺點:
由于需要加鎖,而且可能面臨鎖沖突甚至死鎖的問題,悲觀并發(fā)控制增加了系統(tǒng)的額外開銷,降低了系統(tǒng)的效率,同時也會降低了系統(tǒng)的并行性。
樂觀并發(fā)控制
一、本質
維基百科:在關系數(shù)據(jù)庫管理系統(tǒng)里,樂觀并發(fā)控制(又名“樂觀鎖”,OptimisticConcurrency Control,縮寫“OCC”)是一種并發(fā)控制的方法。它假設多用戶并發(fā)的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分數(shù)據(jù)。
樂觀并發(fā)控制對數(shù)據(jù)修改持樂觀態(tài)度,認為即使在并發(fā)環(huán)境中,外界對數(shù)據(jù)的操作一般是不會造成沖突,所以并不會去加鎖,而是在提交數(shù)據(jù)更新之前,每個事務會先檢查在該事務讀取數(shù)據(jù)后,有沒有其他事務又修改了該數(shù)據(jù)。如果其他事務有更新的話,則讓返回沖突信息,讓用戶決定如何去做下一步,比如說重試或者回滾。
可以看出,樂觀鎖其實也不是實際的鎖,甚至沒有用到鎖來實現(xiàn)并發(fā)控制,而是采取其他方式來判斷能否修改數(shù)據(jù)。樂觀鎖一般是用戶自己實現(xiàn)的一種鎖機制,雖然沒有用到實際的鎖,但是能產生加鎖的效果。
二、實現(xiàn)方式
CAS(比較與交換,Compare and swap) 是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實現(xiàn)多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實現(xiàn)變量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。實現(xiàn)非阻塞同步的方案稱為“無鎖編程算法”( Non-blocking algorithm)。
樂觀鎖基本都是基于 CAS(Compare and swap)算法來實現(xiàn)的。我們先來看下CAS過程,一個CAS操作的過程可以用以下c代碼表示:
intcas(long*addr,longold,longnew) { /* Executes atomically. */ if(*addr!= old) return0; *addr= new; return1; } 復制代碼
CAS有3個操作數(shù),內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做。整個CAS操作是一個原子操作,是不可分割的。
樂觀鎖的實現(xiàn)就類似于上面的過程,主要有以下幾種方式:
版本號標記:在表中新增一個字段:version,用于保存版本號。獲取數(shù)據(jù)的時候同時獲取版本號,然后更新數(shù)據(jù)的時候用以下命令:updatexxx set version=version+1,… where … version="old version" and ....。這時候通過判斷返回結果的影響行數(shù)是否為0來判斷是否更新成功,更新失敗則說明有其他請求已經更新了數(shù)據(jù)了。
時間戳標記:和版本號一樣,只是通過時間戳來判斷。一般來說很多數(shù)據(jù)表都會有更新時間這一個字段,通過這個字段來判斷就不用再新增一個字段了。
待更新字段:如果沒有時間戳字段,而且不想新增字段,那可以考慮用待更新字段來判斷,因為更新數(shù)據(jù)一般都會發(fā)生變化,那更新前可以拿要更新的字段的舊值和數(shù)據(jù)庫的現(xiàn)值進行比對,沒有變化則更新。
所有字段標記:數(shù)據(jù)表所有字段都用來判斷。這種相當于就、不僅僅對某幾個字段做加鎖了,而是對整個數(shù)據(jù)行加鎖,只要本行數(shù)據(jù)發(fā)生變化,就不進行更新。
三、優(yōu)缺點
優(yōu)點:
樂觀并發(fā)控制沒有實際加鎖,所以沒有額外開銷,也不錯出現(xiàn)死鎖問題,適用于讀多寫少的并發(fā)場景,因為沒有額外開銷,所以能極大提高數(shù)據(jù)庫的性能。
缺點:
樂觀并發(fā)控制不適合于寫多讀少的并發(fā)場景下,因為會出現(xiàn)很多的寫沖突,導致數(shù)據(jù)寫入要多次等待重試,在這種情況下,其開銷實際上是比悲觀鎖更高的。而且樂觀鎖的業(yè)務邏輯比悲觀鎖要更為復雜,業(yè)務邏輯上要考慮到失敗,等待重試的情況,而且也無法避免其他第三方系統(tǒng)對數(shù)據(jù)庫的直接修改的情況。
多版本并發(fā)控制
一、本質
維基百科: 多版本并發(fā)控制(Multiversion concurrency control, MCC 或 MVCC),是數(shù)據(jù)庫管理系統(tǒng)常用的一種并發(fā)控制,也用于程序設計語言實現(xiàn)事務內存。
樂觀并發(fā)控制和悲觀并發(fā)控制都是通過延遲或者終止相應的事務來解決事務之間的競爭條件來保證事務的可串行化;雖然前面的兩種并發(fā)控制機制確實能夠從根本上解決并發(fā)事務的可串行化的問題,但是其實都是在解決寫沖突的問題,兩者區(qū)別在于對寫沖突的樂觀程度不同(悲觀鎖也能解決讀寫沖突問題,但是性能就一般了)。而在實際使用過程中,數(shù)據(jù)庫讀請求是寫請求的很多倍,我們如果能解決讀寫并發(fā)的問題的話,就能更大地提高數(shù)據(jù)庫的讀性能,而這就是多版本并發(fā)控制所能做到的事情。
與悲觀并發(fā)控制和樂觀并發(fā)控制不同的是,MVCC是為了解決讀寫鎖造成的多個、長時間的讀操作餓死寫操作問題,也就是解決讀寫沖突的問題。MVCC 可以與前兩者中的任意一種機制結合使用,以提高數(shù)據(jù)庫的讀性能。
數(shù)據(jù)庫的悲觀鎖基于提升并發(fā)性能的考慮,一般都同時實現(xiàn)了多版本并發(fā)控制。不僅是MySQL,包括Oracle、PostgreSQL等其他數(shù)據(jù)庫系統(tǒng)也都實現(xiàn)了MVCC,但各自的實現(xiàn)機制不盡相同,因為MVCC沒有一個統(tǒng)一的實現(xiàn)標準。
總的來說,MVCC的出現(xiàn)就是數(shù)據(jù)庫不滿用悲觀鎖去解決讀-寫沖突問題,因性能不高而提出的解決方案。
二、實現(xiàn)方式
MVCC的實現(xiàn),是通過保存數(shù)據(jù)在某個時間點的快照來實現(xiàn)的。每個事務讀到的數(shù)據(jù)項都是一個歷史快照,被稱為快照讀,不同于當前讀的是快照讀讀到的數(shù)據(jù)可能不是最新的,但是快照隔離能使得在整個事務看到的數(shù)據(jù)都是它啟動時的數(shù)據(jù)狀態(tài)。而寫操作不覆蓋已有數(shù)據(jù)項,而是創(chuàng)建一個新的版本,直至所在事務提交時才變?yōu)榭梢姟?/p>
當前讀和快照讀
什么是MySQL InnoDB下的當前讀和快照讀?
當前讀
像select lock in share mode(共享鎖),select for update ; update, insert ,delete(排他鎖)這些操作都是一種當前讀,為什么叫當前讀?就是它讀取的是記錄的最新版本,讀取時還要保證其他并發(fā)事務不能修改當前記錄,會對讀取的記錄進行加鎖。
快照讀
像不加鎖的select操作就是快照讀,即不加鎖的非阻塞讀;快照讀的前提是隔離級別不是未提交讀和串行化級別,因為未提交讀總是讀取最新的數(shù)據(jù)行,而不是符合當前事務版本的數(shù)據(jù)行。而串行化則會對所有讀取的行都加鎖
三、優(yōu)缺點
MVCC 使大多數(shù)讀操作都可以不用加鎖,這樣設計使得讀數(shù)據(jù)操作很簡單,性能很好,并且也能保證只會讀取到符合標準的行。不足之處是每行記錄都需要額外的存儲空間,需要做更多的行檢查工作,以及一些額外的維護工作。
適用場景
一、悲觀鎖
用來解決讀-寫沖突和寫-寫沖突的的加鎖并發(fā)控制
適用于寫多讀少,寫沖突嚴重的情況,因為悲觀鎖是在讀取數(shù)據(jù)的時候就加鎖的,讀多的場景會需要頻繁的加鎖和很多的的等待時間,而在寫沖突嚴重的情況下使用悲觀鎖可以保證數(shù)據(jù)的一致性
數(shù)據(jù)一致性要求高
可以解決臟讀,幻讀,不可重復讀,第一類更新丟失,第二類更新丟失的問題
二、樂觀鎖
解決寫-寫沖突的無鎖并發(fā)控制
適用于讀多寫少,因為如果出現(xiàn)大量的寫操作,寫沖突的可能性就會增大,業(yè)務層需要不斷重試,這會大大降低系統(tǒng)性能
數(shù)據(jù)一致性要求不高,但要求非常高的響應速度
無法解決臟讀,幻讀,不可重復讀,但是可以解決更新丟失問題
三、MVCC
解決讀-寫沖突的無鎖并發(fā)控制
與上面兩者結合,提升它們的讀性能
可以解決臟讀,幻讀,不可重復讀等事務問題,更新丟失問題除外
到此,相信大家對“什么是樂觀鎖、悲觀鎖和MVCC”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!
當前文章:什么是樂觀鎖、悲觀鎖和MVCC
URL分享:http://www.rwnh.cn/article6/ippiig.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供移動網站建設、企業(yè)建站、營銷型網站建設、軟件開發(fā)、品牌網站建設、ChatGPT
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)