日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

詳解mysql 中的鎖結(jié)構(gòu)

瀏覽:236日期:2023-10-10 10:38:48

Mysql 支持3中鎖結(jié)構(gòu)

表級鎖,開銷小,加鎖快,不會出現(xiàn)死鎖,鎖定的粒度大,沖突概率高,并發(fā)度最低 行級鎖,開銷小,加鎖慢,會出現(xiàn)死鎖,鎖定粒度小,沖突概率最低,并發(fā)度最高 頁面鎖,開銷和加鎖處于表鎖和行鎖之間,會出現(xiàn)死鎖,鎖粒度基于表和行之間,并發(fā)一般

InnoDB鎖問題

InnoDB與MyISAM的最大不同有兩點:一是支持事務(wù)(TRANSACTION);二是采用了行級鎖。 行級鎖和表級鎖本來就有許多不同之處,另外,事務(wù)的引入也帶來了一些新問題。

InnoDB的行鎖模式及加鎖方法

InnoDB實現(xiàn)了以下兩種類型的行鎖。

共享鎖(s):允許一個事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。 排他鎖(X):允許獲取排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同的數(shù)據(jù)集共享讀鎖和排他寫鎖。

另外,為了允許行鎖和表鎖共存,實現(xiàn)多粒度鎖機制,InnoDB還有兩種內(nèi)部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行共享鎖,事務(wù)在給一個數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖。 意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加排他鎖,事務(wù)在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。 當前鎖模式和請求鎖模式 X IX S IS X 沖突 沖突 沖突 沖突 IX 沖突 兼容 沖突 兼容 S 沖突 沖突 兼容 兼容 IS 沖突 兼容 兼容 兼容

InnoDB行鎖是通過索引上的索引項來實現(xiàn)的,這一點MySQL與Oracle不同,后者是通過在數(shù)據(jù)中對相應(yīng)數(shù)據(jù)行加鎖來實現(xiàn)的。InnoDB這種行鎖實現(xiàn)特點意味者:只有通過索引條件檢索數(shù)據(jù),InnoDB才會使用行級鎖,否則,InnoDB將使用表鎖!

Next-Key鎖

當我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請求共享或排他鎖時,InnoDB會給符合條件的已有數(shù)據(jù)的索引項加鎖;對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,InnoDB也會對這個“間隙”加鎖,這種鎖機制不是所謂的間隙鎖(Next-Key鎖)。舉例來說,假如emp表中只有101條記錄,其empid的值分別是1,2,...,100,101,下面的SQL:

SELECT * FROM emp WHERE empid > 100 FOR UPDATE

是一個范圍條件的檢索,InnoDB不僅會對符合條件的empid值為101的記錄加鎖,也會對empid大于101(這些記錄并不存在)的“間隙”加鎖。InnoDB使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關(guān)隔離級別的要求,對于上面的例子,要是不使用間隙鎖,如果其他事務(wù)插入了empid大于100的任何記錄,那么本事務(wù)如果再次執(zhí)行上述語句,就會發(fā)生幻讀;另一方面,是為了滿足其恢復(fù)和復(fù)制的需要。有關(guān)其恢復(fù)和復(fù)制對機制的影響,以及不同隔離級別下InnoDB使用間隙鎖的情況。很顯然,在使用范圍條件檢索并鎖定記錄時,InnoDB這種加鎖機制會阻塞符合條件范圍內(nèi)鍵值的并發(fā)插入,這往往會造成嚴重的鎖等待。因此,在實際開發(fā)中,尤其是并發(fā)插入比較多的應(yīng)用,我們要盡量優(yōu)化業(yè)務(wù)邏輯,盡量使用相等條件來訪問更新數(shù)據(jù),避免使用范圍條件。

什么時候使用表鎖?

對于InnoDB表,在絕大部分情況下都應(yīng)該使用行級鎖,因為事務(wù)和行鎖往往是我們之所以選擇InnoDB表的理由。但在個另特殊事務(wù)中,也可以考慮使用表級鎖。

第一種情況是:事務(wù)需要更新大部分或全部數(shù)據(jù),表又比較大,如果使用默認的行鎖,不僅這個事務(wù)執(zhí)行效率低,而且可能造成其他事務(wù)長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務(wù)的執(zhí)行速度。

第二種情況是:事務(wù)涉及多個表,比較復(fù)雜,很可能引起死鎖,造成大量事務(wù)回滾。這種情況也可以考慮一次性鎖定事務(wù)涉及的表,從而避免死鎖、減少數(shù)據(jù)庫因事務(wù)回滾帶來的開銷。

當然,應(yīng)用中這兩種事務(wù)不能太多,否則,就應(yīng)該考慮使用MyISAM表。 在InnoDB下 ,使用表鎖要注意以下兩點。

(1)使用LOCK TALBES雖然可以給InnoDB加表級鎖,但必須說明的是,表鎖不是由InnoDB存儲引擎層管理的,而是由其上一層MySQL Server負責(zé)的,僅當autocommit=0、innodb_table_lock=1(默認設(shè)置)時,InnoDB層才能知道MySQL加的表鎖,MySQL Server才能感知InnoDB加的行鎖,這種情況下,InnoDB才能自動識別涉及表級鎖的死鎖;否則,InnoDB將無法自動檢測并處理這種死鎖。

(2)在用LOCAK TABLES對InnoDB鎖時要注意,要將AUTOCOMMIT設(shè)為0,否則MySQL不會給表加鎖;事務(wù)結(jié)束前,不要用UNLOCAK TABLES釋放表鎖,因為UNLOCK TABLES會隱含地提交事務(wù);COMMIT或ROLLBACK產(chǎn)不能釋放用LOCAK TABLES加的表級鎖,必須用UNLOCK TABLES釋放表鎖,正確的方式見如下語句。 例如,如果需要寫表t1并從表t讀,可以按如下做:

SET AUTOCOMMIT=0;LOCAK TABLES t1 WRITE, t2 READ, ...;[do something with tables t1 and here];COMMIT;UNLOCK TABLES;

死鎖

在InnoDB中,除單個SQL組成的事務(wù)外,鎖是逐步獲得的,這就決定了InnoDB發(fā)生死鎖是可能的。 發(fā)生死鎖后,InnoDB一般都能自動檢測到,并使一個事務(wù)釋放鎖并退回,另一個事務(wù)獲得鎖,繼續(xù)完成事務(wù)。但在涉及外部鎖,或涉及鎖的情況下,InnoDB并不能完全自動檢測到死鎖,這需要通過設(shè)置鎖等待超時參數(shù)innodb_lock_wait_timeout來解決。需要說明的是,這個參數(shù)并不是只用來解決死鎖問題,在并發(fā)訪問比較高的情況下,如果大量事務(wù)因無法立即獲取所需的鎖而掛起,會占用大量計算機資源,造成嚴重性能問題,甚至拖垮數(shù)據(jù)庫。我們通過設(shè)置合適的鎖等待超時閾值,可以避免這種情況發(fā)生。

通常來說,死鎖都是應(yīng)用設(shè)計的問題,通過調(diào)整業(yè)務(wù)流程、數(shù)據(jù)庫對象設(shè)計、事務(wù)大小、以及訪問數(shù)據(jù)庫的SQL語句,絕大部分都可以避免。下面就通過實例來介紹幾種死鎖的常用方法。

(1)在應(yīng)用中,如果不同的程序會并發(fā)存取多個表,應(yīng)盡量約定以相同的順序為訪問表,這樣可以大大降低產(chǎn)生死鎖的機會。如果兩個session訪問兩個表的順序不同,發(fā)生死鎖的機會就非常高!但如果以相同的順序來訪問,死鎖就可能避免。

(2)在程序以批量方式處理數(shù)據(jù)的時候,如果事先對數(shù)據(jù)排序,保證每個線程按固定的順序來處理記錄,也可以大大降低死鎖的可能。

(3)在事務(wù)中,如果要更新記錄,應(yīng)該直接申請足夠級別的鎖,即排他鎖,而不應(yīng)該先申請共享鎖,更新時再申請排他鎖,甚至死鎖。

(4)在REPEATEABLE-READ隔離級別下,如果兩個線程同時對相同條件記錄用SELECT...ROR UPDATE加排他鎖,在沒有符合該記錄情況下,兩個線程都會加鎖成功。程序發(fā)現(xiàn)記錄尚不存在,就試圖插入一條新記錄,如果兩個線程都這么做,就會出現(xiàn)死鎖。這種情況下,將隔離級別改成READ COMMITTED,就可以避免問題。

(5)當隔離級別為READ COMMITED時,如果兩個線程都先執(zhí)行SELECT...FOR UPDATE,判斷是否存在符合條件的記錄,如果沒有,就插入記錄。此時,只有一個線程能插入成功,另一個線程會出現(xiàn)鎖等待,當?shù)冢眰€線程提交后,第2個線程會因主鍵重出錯,但雖然這個線程出錯了,卻會獲得一個排他鎖!這時如果有第3個線程又來申請排他鎖,也會出現(xiàn)死鎖。對于這種情況,可以直接做插入操作,然后再捕獲主鍵重異常,或者在遇到主鍵重錯誤時,總是執(zhí)行ROLLBACK釋放獲得的排他鎖。

MyISAM 和 InnoDB 區(qū)別

對于MyISAM的表鎖,主要有以下幾點

(1)共享讀鎖(S)之間是兼容的,但共享讀鎖(S)和排他寫鎖(X)之間,以及排他寫鎖之間(X)是互斥的,也就是說讀和寫是串行的。(2)在一定條件下,MyISAM允許查詢和插入并發(fā)執(zhí)行,我們可以利用這一點來解決應(yīng)用中對同一表和插入的鎖爭用問題。(3)MyISAM默認的鎖調(diào)度機制是寫優(yōu)先,這并不一定適合所有應(yīng)用,用戶可以通過設(shè)置LOW_PRIPORITY_UPDATES參數(shù),或在INSERT、UPDATE、DELETE語句中指定LOW_PRIORITY選項來調(diào)節(jié)讀寫鎖的爭用。(4)由于表鎖的鎖定粒度大,讀寫之間又是串行的,因此,如果更新操作較多,MyISAM表可能會出現(xiàn)嚴重的鎖等待,可以考慮采用InnoDB表來減少鎖沖突。

對于InnoDB表,主要有以下幾點

(1)InnoDB的行銷是基于索引實現(xiàn)的,如果不通過索引訪問數(shù)據(jù),InnoDB會使用表鎖。(2)InnoDB間隙鎖機制,以及InnoDB使用間隙鎖的原因。(3)在不同的隔離級別下,InnoDB的鎖機制和一致性讀策略不同。(4)MySQL的恢復(fù)和復(fù)制對InnoDB鎖機制和一致性讀策略也有較大影響。(5)鎖沖突甚至死鎖很難完全避免。

在了解InnoDB的鎖特性后,用戶可以通過設(shè)計和SQL調(diào)整等措施減少鎖沖突和死鎖,包括:

盡量使用較低的隔離級別 精心設(shè)計索引,并盡量使用索引訪問數(shù)據(jù),使加鎖更精確,從而減少鎖沖突的機會。 選擇合理的事務(wù)大小,小事務(wù)發(fā)生鎖沖突的幾率也更小。 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數(shù)據(jù)的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產(chǎn)生死鎖。 不同的程序訪問一組表時,應(yīng)盡量約定以相同的順序訪問各表,對一個表而言,盡可能以固定的順序存取表中的行。這樣可以大減少死鎖的機會。 盡量用相等條件訪問數(shù)據(jù),這樣可以避免間隙鎖對并發(fā)插入的影響。 不要申請超過實際需要的鎖級別;除非必須,查詢時不要顯示加鎖。 對于一些特定的事務(wù),可以使用表鎖來提高處理速度或減少死鎖的可能

MySql樂觀鎖悲觀鎖

悲觀鎖

悲觀鎖的特點是先獲取鎖,再進行業(yè)務(wù)操作,即“悲觀”的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業(yè)務(wù)操作。通常所說的“一鎖二查三更新”即指的是使用悲觀鎖。通常來講在數(shù)據(jù)庫上的悲觀鎖需要數(shù)據(jù)庫本身提供支持,即通過常用的select … for update操作來實現(xiàn)悲觀鎖。當數(shù)據(jù)庫執(zhí)行select for update時會獲取被select中的數(shù)據(jù)行的行鎖,因此其他并發(fā)執(zhí)行的select for update如果試圖選中同一行則會發(fā)生排斥(需要等待行鎖被釋放),因此達到鎖的效果。select for update獲取的行鎖會在當前事務(wù)結(jié)束時自動釋放,因此必須在事務(wù)中使用。

這里需要注意的一點是不同的數(shù)據(jù)庫對select for update的實現(xiàn)和支持都是有所區(qū)別的,例如oracle支持select for update no wait,表示如果拿不到鎖立刻報錯,而不是等待,mysql就沒有no wait這個選項。另外mysql還有個問題是select for update語句執(zhí)行中所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在mysql中用悲觀鎖務(wù)必要確定走了索引,而不是全表掃描。

樂觀鎖

樂觀鎖的特點先進行業(yè)務(wù)操作,不到萬不得已不去拿鎖。即“樂觀”的認為拿鎖多半是會成功的,因此在進行完業(yè)務(wù)操作需要實際更新數(shù)據(jù)的最后一步再去拿一下鎖就好。

樂觀鎖在數(shù)據(jù)庫上的實現(xiàn)完全是邏輯的,不需要數(shù)據(jù)庫提供特殊的支持。一般的做法是在需要鎖的數(shù)據(jù)上增加一個版本號,或者時間戳,然后按照如下方式實現(xiàn):

1. SELECT data AS old_data, version AS old_version FROM …;2. 根據(jù)獲取的數(shù)據(jù)進行業(yè)務(wù)操作,得到new_data和new_version3. UPDATE SET data = new_data, version = new_version WHERE version = old_versionif (updated row > 0) { // 樂觀鎖獲取成功,操作完成} else { // 樂觀鎖獲取失敗,回滾并重試}

在數(shù)據(jù)庫內(nèi)部update同一行的時候是不允許并發(fā)的,即數(shù)據(jù)庫每次執(zhí)行一條update語句時會獲取被update行的寫鎖,直到這一行被成功更新后才釋放。因此在業(yè)務(wù)操作進行前獲取需要鎖的數(shù)據(jù)的當前版本號,然后實際更新數(shù)據(jù)時再次對比版本號確認與之前獲取的相同,并更新版本號,即可確認這之間沒有發(fā)生并發(fā)的修改。如果更新失敗即可認為老版本的數(shù)據(jù)已經(jīng)被并發(fā)修改掉而不存在了,此時認為獲取鎖失敗,需要回滾整個業(yè)務(wù)操作并可根據(jù)需要重試整個過程。

樂觀鎖在不發(fā)生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發(fā)生失敗回滾開銷則比較大,因此適合用在取鎖失敗概率比較小的場景,可以提升系統(tǒng)并發(fā)性能樂觀鎖還適用于一些比較特殊的場景,例如在業(yè)務(wù)操作過程中無法和數(shù)據(jù)庫保持連接等悲觀鎖無法適用的地方

以上就是詳解mysql 中的鎖結(jié)構(gòu)的詳細內(nèi)容,更多關(guān)于MySQL 鎖結(jié)構(gòu)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久a爱视频| 国产91在线精品| 风间由美中文字幕在线看视频国产欧美 | 亚洲精品护士| 免费欧美在线视频| 午夜欧美视频| 在线视频精品| 国产一区二区三区自拍| 日韩欧美一区二区三区在线视频 | 亚洲一本视频| 欧美日韩一二三四| 久久久久久久久99精品大| 粉嫩av一区二区三区四区五区 | 久久高清免费观看| 红桃视频国产精品| 久久成人亚洲| 久久国产人妖系列| 九九九精品视频| 六月丁香综合在线视频| 成人国产精选| 免费毛片在线不卡| 亚洲精品无吗| 国产一区福利| 蜜桃视频欧美| 亚洲三区欧美一区国产二区| 丝袜美腿一区二区三区| 日韩精品一页| 国产精品色在线网站| 久久久久久一区二区| 国产精品试看| 国产欧美另类| 91精品婷婷色在线观看| 麻豆9191精品国产| 麻豆精品久久| 午夜在线精品偷拍| 老司机免费视频一区二区三区| 国产夫妻在线| 婷婷视频一区二区三区| 国产成人a视频高清在线观看| 欧美成人精品| 欧美久久精品| 日本一二区不卡| 久久久久久久久99精品大| 日本成人在线视频网站| 日韩免费小视频| 国产精品一国产精品| 高清久久一区| 欧美日韩国产综合网| 视频一区在线播放| 久久久久久久久99精品大| 日韩免费久久| 久久精品资源| 欧美日韩99| 一区二区三区四区精品视频| 加勒比视频一区| 91大神在线观看线路一区| 亚洲激情五月| 久久国产精品色av免费看| 亚洲在线观看| 一区二区三区视频免费观看| 动漫av一区| 欧美国产偷国产精品三区| 欧美国产免费| 国产精品一区二区精品| 天堂va欧美ⅴa亚洲va一国产| 狠狠久久婷婷| 中文在线一区| 国产精品视区| 国产农村妇女精品一二区| 蜜臀av免费一区二区三区| 91精品国产91久久久久久黑人| 欧美国产一级| 成人午夜亚洲| 热三久草你在线| 亚洲成人精品| 亚洲男女av一区二区| 国产一区91| 日韩高清不卡一区| 国产精品久久久久久模特| 国产欧美激情| 不卡一二三区| 天堂成人国产精品一区| 日韩高清在线不卡| 国产精品videossex| 91亚洲国产| 亚洲激情二区| 久久国际精品| 免费一级欧美在线观看视频| 中文字幕在线看片| 久久av一区| 国产精品玖玖玖在线资源| 麻豆成全视频免费观看在线看| 国产一区亚洲| 欧美日本三区| 91精品国产成人观看| 国产精品毛片一区二区三区| 欧美日韩精品一区二区三区视频| 精品国产网站| 免费观看日韩电影| 国际精品欧美精品| 亚洲综合国产| 国产精品99视频| 91高清一区| 美女视频免费精品| 午夜在线一区二区| 精品国产美女a久久9999| 午夜久久黄色| 激情不卡一区二区三区视频在线| 亚洲专区欧美专区| 日本久久精品| 国产九九精品| 日本国产一区| 中文精品视频| 日韩久久一区二区三区| 国产无遮挡裸体免费久久| 狠狠干综合网| 99久久久久国产精品| 亚洲欧美日韩国产一区| 精品国产乱码久久久| 蜜臀久久99精品久久久久久9| 天堂av在线| 国产毛片精品| 亚洲伊人精品酒店| 免费不卡中文字幕在线| 精品少妇一区| 国产精品啊v在线| 日韩精品久久久久久久软件91| 国产精品久久久久av电视剧| 精品一区av| 美女视频网站久久| 国产精品hd| 国产亚洲久久| 免费在线观看成人| 先锋影音久久久| 在线综合欧美| 免费人成精品欧美精品| 欧美在线综合| 亚洲一区二区三区高清不卡| 亚洲午夜视频| 国产亚洲精品v| 一区二区日韩免费看| 久久午夜精品一区二区| 久久不射中文字幕| 日韩精品第一| 欧美激情aⅴ一区二区三区| 蜜桃久久久久| sm久久捆绑调教精品一区| 国产精品毛片久久久| 麻豆精品av| sm久久捆绑调教精品一区| 99精品美女| 视频一区中文字幕国产| 亚洲精品大片| 激情综合婷婷| 国产美女精品| 国产精品中文字幕制服诱惑| 9999国产精品| 宅男噜噜噜66国产日韩在线观看| 亚洲青青久久| 中文字幕在线高清| 免费观看在线综合色| 另类欧美日韩国产在线| 久久久久久网| 久久国产99| 日韩av在线播放网址| 偷拍欧美精品| 美女视频网站久久| 日韩视频二区| 精品日韩在线| 亚洲色图综合| 亚洲啊v在线| 国产区精品区| 亚洲一区二区三区免费在线观看| 国产精品毛片aⅴ一区二区三区| 久久高清免费| 国产精品久久久网站| 国产一级久久| 精品欧美日韩精品| 一区二区三区四区精品视频| 日韩国产一区二区三区| 欧美一区免费| 久久亚洲国产精品一区二区| 国产自产自拍视频在线观看| 午夜久久av | 亚洲一区二区成人| 国产资源在线观看入口av| 国产精品色在线网站| 日韩欧美在线精品| 亚洲高清二区| 日本精品不卡| 日本蜜桃在线观看视频| 免费在线亚洲欧美| 久久国产三级精品| 国产亚洲久久| 欧美日韩一区二区三区不卡视频 | 蜜桃视频免费观看一区| 激情婷婷欧美| 99精品视频精品精品视频| 岛国av在线网站| 91麻豆精品|