MyISAM與InnoDB關(guān)于鎖方面的區(qū)別:
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了石鼓免費(fèi)建站歡迎大家使用!
注:
實(shí)際上在不走索引的時(shí)候,InnoDB的實(shí)現(xiàn)方式和MyIsam的表鎖方式不同,單條索引記錄上加鎖,record lock鎖住的永遠(yuǎn)是索引,而非記錄本身,即使該表上沒有任何索引,那么innodb會(huì)在后臺(tái)創(chuàng)建一個(gè)隱藏的聚集主鍵索引,那么鎖住的就是這個(gè)隱藏的聚集主鍵索引。所以說當(dāng)一條sql沒有走任何索引時(shí),那么將會(huì)在每一條聚集索引后面加X鎖(排他鎖),此時(shí)想改變樹型結(jié)構(gòu)即索引結(jié)構(gòu)的話,是會(huì)被鎖住的,這個(gè)類似于表鎖,但原理上和表鎖是完全不同的
MyISAM適合的場景:
InnoDB適合的場景:
數(shù)據(jù)庫鎖的分類:
總結(jié):
MyISAM默認(rèn)使用的是表級(jí)鎖,不支持行級(jí)鎖。InnoDB默認(rèn)用的是行級(jí)鎖,也支持表級(jí)鎖。無論是表級(jí)鎖還是行級(jí)鎖,均分為共享鎖和排他鎖,它們的關(guān)系如下表所示(X:排他鎖,S:共享鎖):
事務(wù)并發(fā)訪問引起的問題以及如何避免:
1.更新丟失:
即一個(gè)事務(wù)的更新覆蓋了另一個(gè)事務(wù)的更新;由于現(xiàn)在主流數(shù)據(jù)庫都會(huì)自動(dòng)加鎖來避免更新丟失的情況,所以在數(shù)據(jù)庫層面通常不會(huì)發(fā)生這個(gè)問題。例如MySQL所有事務(wù)隔離級(jí)別在數(shù)據(jù)庫層面上均可避免更新丟失
下圖模擬了更新丟失的過程:
2.臟讀(Dirty read):
即一個(gè)事務(wù)讀到另一個(gè)事務(wù)的未提交數(shù)據(jù);該問題在READ-COMMITTED(讀已提交)以上的事務(wù)隔離級(jí)別可避免
3.不可重復(fù)讀(Non-repeatable read):
即事務(wù)A多次讀取同一數(shù)據(jù),但事務(wù)B在事務(wù)A多次讀取的過程中對(duì)該數(shù)據(jù)做了更新操作并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí)結(jié)果不一致;該問題在REPEATABLE-READ(可重復(fù)讀)以上的事務(wù)隔離級(jí)別可避免,這也是MySQL的默認(rèn)隔離級(jí)別
4.幻讀(Phantom read):
事務(wù)A讀取以搜索條件相匹配的若干行數(shù)據(jù),而事務(wù)B則對(duì)事務(wù)A查詢匹配的數(shù)據(jù)進(jìn)行了插入或刪除操作,導(dǎo)致事務(wù)A多次讀取的結(jié)果集行數(shù)不一致;該問題在SERIALIZABLE(串行化)以上的事務(wù)隔離級(jí)別可避免,需要注意的是:在MySQL數(shù)據(jù)庫中,REPEATABLE-READ事務(wù)隔離級(jí)別下也可以避免幻讀
總結(jié):
表象:快照讀(非阻塞讀)-- 偽MVCC(多版本并發(fā)控制)
內(nèi)在:next-key鎖(行級(jí)鎖+gap鎖)
首先我們需要知道兩個(gè)概念:當(dāng)前讀和快照讀;當(dāng)前讀其實(shí)就是加了鎖的增刪改查語句,例:
之所以叫當(dāng)前讀,是因?yàn)樽x取的是當(dāng)前記錄的最新版本,而RR事務(wù)隔離級(jí)別下在讀取數(shù)據(jù)之后還需要保證其他事務(wù)不能修改當(dāng)前記錄,那么就會(huì)對(duì)讀取的記錄加next-key鎖,所以RR事務(wù)隔離級(jí)別下的當(dāng)前讀可以避免發(fā)生幻讀現(xiàn)象:
快照讀則是不加鎖的非阻塞讀,例如不加鎖的普通select操作。但需要注意的是在串行化的事務(wù)隔離級(jí)別下,任何的增刪改查操作都會(huì)被加鎖。
在mysql中,讀已提交隔離級(jí)別下,快照讀和當(dāng)前讀都是讀到同樣的數(shù)據(jù)。而在可重復(fù)讀隔離級(jí)別下,快照讀讀到的是開啟事務(wù)時(shí)第一條select語句讀到的快照版本數(shù)據(jù),當(dāng)前讀則是會(huì)讀到當(dāng)前數(shù)據(jù)庫中最新的數(shù)據(jù)。
RC、RR級(jí)別下的InnoDB的快照讀(非阻塞讀)是如何實(shí)現(xiàn)的:
事務(wù)對(duì)行的更新過程:
在之前的小節(jié)中,我們了解到在MySQL的RR事務(wù)隔離級(jí)別下,是可以避免幻讀的。但并不意味著快照讀是避免發(fā)生幻讀現(xiàn)象的根本,因?yàn)榭煺兆x只是讀的發(fā)生變化前的歷史數(shù)據(jù)。實(shí)際在RR及SERIALIZABLE事務(wù)隔離級(jí)別下真正防止幻讀發(fā)生的原因是事務(wù)對(duì)數(shù)據(jù)加上了next-key鎖,而next-key鎖由行鎖和gap鎖兩部分組成。行鎖就不多說了,gap鎖才是重點(diǎn),所謂gap就是索引樹中插入新記錄的間隙,而gap鎖是用于鎖定一個(gè)間隙范圍但不包括記錄本身,gap鎖的目的是為了防止同一事務(wù)的兩次當(dāng)前讀而導(dǎo)致出現(xiàn)幻讀的情況。
gap鎖只在RR和SERIALIZABLE事務(wù)隔離級(jí)別中存在,其他的隔離級(jí)別是沒有的,所以RC和RU是無法避免幻讀的。這里我們主要討論RR事務(wù)隔離級(jí)別下gap鎖出現(xiàn)的場景:
where條件全部命中,只會(huì)加行鎖:
走非唯一索引時(shí)會(huì)對(duì)該索引間隙加gap鎖:
不走索引則會(huì)對(duì)表里所有的間隙加gap鎖,其效果就類似于表級(jí)鎖了,但是其代價(jià)比表級(jí)鎖更大:
總結(jié):
無論是當(dāng)前讀還是快照讀,在innodb的RR的事務(wù)隔離級(jí)別下都可以避免幻讀。在快照讀的情況下,innodb通過mvcc來避免幻讀;在當(dāng)前讀的情況下,innodb通過next-key鎖來避免幻讀。
網(wǎng)站標(biāo)題:數(shù)據(jù)庫之鎖模塊
本文鏈接:http://www.rwnh.cn/article14/igehge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、品牌網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)站收錄、App設(shè)計(jì)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)