mysql事務(wù)與鎖機(jī)制

什么是事務(wù)瞪慧?

官方點(diǎn)說,事務(wù)就是數(shù)據(jù)庫管理系統(tǒng)執(zhí)行過程中的一個邏輯單位茅主,由一個有限的數(shù)據(jù)庫操作作序列構(gòu)成舞痰。

通俗點(diǎn)說,事務(wù)就是一組操作要么同時成功要么同時失敗诀姚。

事務(wù)的四大特性(ACID):

1.原子性(atomicity):一個事務(wù)必須視為一個不可分割的最小工作單元响牛,整個事務(wù)中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務(wù)來說呀打,不可能只執(zhí)行其中的一部分操作矢赁,這就是事務(wù)的原子性。

2.一致性(consistency):數(shù)據(jù)庫總數(shù)從一個一致性的狀態(tài)轉(zhuǎn)換到另一個一致性的狀態(tài)贬丛。

3.隔離性(isolation):一個事務(wù)所做的修改在最終提交以前撩银,對其他事務(wù)是不可見的。

4.持久性(durability):一旦事務(wù)提交瘫寝,則其所做的修改就會永久保存到數(shù)據(jù)庫中蜒蕾。此時即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會丟失焕阿。

事務(wù)并發(fā)帶來的問題:

1.臟讀:臟讀是指一個事務(wù)在處理過程中讀取了另一個事務(wù)未提交的數(shù)據(jù)咪啡。

2.不可重復(fù)讀:指的是在一個事務(wù)處理中讀取到其他事務(wù)修改或刪除并提交的數(shù)據(jù),導(dǎo)致多次讀取結(jié)果不一致暮屡。

3.幻讀:指的是在一個事務(wù)處理中讀取到其他事務(wù)插入并提交的數(shù)據(jù)撤摸,導(dǎo)致多次讀取結(jié)果不一致。

事務(wù)并發(fā)帶來的三大問題其實(shí)都是數(shù)據(jù)庫讀一致性問題褒纲,必須由數(shù)據(jù)庫提供一定的事務(wù)隔離機(jī)制來解決准夷。

mysql事務(wù)的隔離級別:

事務(wù)隔離級別臟讀不可重復(fù)讀幻讀

讀未提交(read-uncommitted)可能可能可能

不可重復(fù)讀(read-committed)不可能可能可能

可重復(fù)讀(repeatable-read)不可能不可能在InnoDB中不可能

串行化(serializable)不可能不可能不可能

為什么InnoDB中在rr級別的時候就解決了幻讀這個問題?

MVCC與LBCC

如果要解決讀一致性問題莺掠,保證一個事務(wù)前后讀取數(shù)據(jù)結(jié)果的一致性衫嵌,實(shí)現(xiàn)事務(wù)隔離應(yīng)該怎么做?

簡單思考下解決方案:

LBCC(全稱Lock Based Concyrrency Control):在讀取數(shù)據(jù)前對其加鎖彻秆,阻止其他事務(wù)對數(shù)據(jù)進(jìn)行修改楔绞。

MVCC(全稱Multi Version Concurrency Control):生成一個數(shù)據(jù)請求時間點(diǎn)的一致性數(shù)據(jù)快照(snapshot),并用這個快照來提供一定級別(語句級或者事務(wù)級)的一致性讀取。

InnoDB中怎么實(shí)現(xiàn)的MVCC

其實(shí)InnoDB中唇兑,自動為每一行數(shù)據(jù)添加了三個隱藏字段:

DB_ROW_ID(6字節(jié)):行標(biāo)識酒朵,前邊的文章中提到過這個字段。

DB_TRX_ID(6字節(jié)):創(chuàng)建版本號扎附,插入或更新行的最后一個事務(wù)的id蔫耽,自動遞增。

DB_ROLL_PIR(7字節(jié)):刪除版本號留夜,用于回滾匙铡。

主要記住,在InnoDB中碍粥,一個事務(wù)開始時慰枕,會生成一個當(dāng)前時間點(diǎn)的數(shù)據(jù)快照(可以理解為一個副本),只要事務(wù)不結(jié)束即纲,他就只能在這個數(shù)據(jù)快照里查找數(shù)據(jù)具帮,也就是只能查找到創(chuàng)建版本號小于當(dāng)前事務(wù)id的數(shù)據(jù)和刪除版本號大于當(dāng)前事務(wù)id的數(shù)據(jù)(或者是在創(chuàng)建版本號小于當(dāng)前事務(wù)id的前提下,沒有刪除版本號的數(shù)據(jù))

在InnoDB中MVCC和鎖是相互配合使用的,下邊就看看鎖的東西蜂厅。

表鎖與行鎖的區(qū)別:

鎖定粒度:表鎖 > 行鎖

加鎖效率:表鎖 > 行鎖

沖突概率:表鎖 > 行鎖

并發(fā)性能:表鎖 < 行鎖

注意:MYISAM引擎只支持表鎖匪凡,InnoDB既支持表鎖也支持行鎖

行鎖

共享鎖(Shared Locks):

又稱為讀鎖,簡稱s鎖掘猿,顧名思義共享鎖就是多個事務(wù)對于同一數(shù)據(jù)可以共享一把鎖病游,都能訪問到數(shù)據(jù),但是只能讀不能寫稠通,不然容易造成死鎖衬衬。

加鎖方式:在select語句后加LOCK IN SHARE MODE;

釋鎖方式:commit / rollback

排他鎖(Exclusive Locks):

又稱為寫鎖,簡稱x鎖改橘,排他鎖不能和其他鎖共存滋尉,如一個事務(wù)獲取了一個數(shù)據(jù)行的排他鎖,其他事務(wù)就不能獲取該行的鎖(包括共享鎖和排他鎖)飞主,只有獲取到該行的排他鎖的事務(wù)是可以對數(shù)據(jù)進(jìn)行讀取和修改狮惜。

加鎖方式:

1.手動加鎖:在語句后加FOR UPDATE;(select時需手動)

2.自動加鎖:在insert / update / delete 語句時或自動加排他鎖

釋鎖方式:commit / rollback

注意:innoDB中獲取鎖超時間默認(rèn)為50秒,查看語句為show variables like 'innodb_lock_wait_timeout';碌识。

表鎖

意向共享鎖(Intention Shared Lock):

簡稱IS鎖碾篡,表示事務(wù)準(zhǔn)備給數(shù)據(jù)行進(jìn)行加入共享鎖,也就是說一個數(shù)據(jù)行加共享鎖之前必須先獲得該表的IS鎖筏餐。

意向排他鎖(Intention Exclusive Lock):

簡稱IX鎖开泽,表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入排他鎖,說明事務(wù)在一個數(shù)據(jù)行加排他鎖前必須要獲得該表的IX鎖魁瞪。

注意:意向鎖是由數(shù)據(jù)引擎自己維護(hù)的穆律,用戶是無法手動操作意向鎖的。

問:為什么需要表級別的意向鎖佩番?

答:假如要給一張表加表鎖众旗,那么這個加表鎖的前提是沒有其他任何事務(wù)已經(jīng)鎖住了這張表的任意一行數(shù)據(jù)罢杉。那么怎么來確定這個前提呢趟畏?

必然要有一個全表掃描才能確定每一行數(shù)據(jù)都沒有被加鎖。如果這張表數(shù)據(jù)比較大呢滩租?有千萬數(shù)據(jù)赋秀,那這個全表掃描的過程就要消耗很多時間才能確定能不能加表鎖,并且如果在掃描的過程中萬一有其他事務(wù)來加鎖怎么辦律想,所以說猎莲,全表掃描加表鎖這種方式既慢并且消耗性能,帶來嚴(yán)重的并發(fā)問題技即。為了解決這一問題著洼,才有了意向鎖。加表鎖的時候只要看一下這個表上有沒有意向鎖就ok了,因?yàn)槟慵有墟i的時候都會先獲取到表的意向鎖才行身笤。意向鎖就是為了提高加表鎖的效率豹悬。

問:鎖的作用?

答:和Java中的鎖一樣液荸,都是為了解決資源競爭的問題瞻佛,Java中的資源是對象。而數(shù)據(jù)庫中的資源就是表和行數(shù)據(jù)娇钱,鎖就是為了解決對于事務(wù)并發(fā)訪問的問題伤柄。

問:鎖到底鎖住了什么?是一行數(shù)據(jù)文搂?還是一個字段适刀?

InnoDB行鎖原理

針對上述問題,其實(shí)有三種情況:

1.沒有索引的表上加行鎖细疚,會鎖住整張表蔗彤,出現(xiàn)鎖表的情況。

2.有主鍵索引的表上加行鎖疯兼,會鎖住索引然遏。

3.用唯一索引(輔助索引)的字段加行鎖,會鎖住輔助索引和主鍵索引吧彪。

在InnoDB中待侵,行鎖就是鎖住索引記錄來實(shí)現(xiàn)的,加鎖的時候在mysql自帶的information_schema庫中的INN0DB_LOCKS表中可以看到:

lock_type:鎖類型姨裸;lock_table:加鎖的表秧倾;lock_index:鎖住的索引

問:沒有索引的表上加行鎖為什么會鎖表?

注意:在之前的文章中說過傀缩,InnoDB中一張表是不可能沒有索引的那先,如果用戶沒定義,默認(rèn)就會用隱藏的字段ROW_ID作為聚集索引赡艰。那么加行鎖的時候售淡,條件沒有命中索引(因?yàn)橛玫氖请[藏字段作為索引,那么肯定不能命中翱犊濉)揖闸,就會走全表掃描,不得不把所有的聚集索引全都鎖住料身,所以會出現(xiàn)鎖表的情況汤纸。

問:為什么用唯一索引加行鎖時,會鎖住主鍵索引芹血?

這就又涉及到前邊的知識——回表贮泞,因?yàn)镮nnoDB中楞慈,輔助索引的葉子節(jié)點(diǎn)上存放的是主鍵索引,索引用輔助索引加行鎖時會先鎖住輔助索引啃擦,然后鎖住主鍵索引抖部。本質(zhì)上其實(shí)還是鎖住了主鍵索引。那么鎖到底鎖住了什么议惰?相信大家心里已經(jīng)有答案了慎颗。

InnoDB行鎖算法

主要有三種算法:

1.記錄鎖(Record Lock)

鎖定記錄,在唯一性索引(唯一/主鍵)等值查詢時言询,精準(zhǔn)匹配到一個索引記錄的時候會使用記錄鎖俯萎。

(如下圖)比如用where id = 4這個條件時,就會精準(zhǔn)匹配到一個索引記錄运杭。

2.間隙鎖(Gap Lock)

鎖定區(qū)間夫啊,鎖定是的是數(shù)據(jù)庫不存在的區(qū)間范圍,Gap Lock相互之間不會沖突辆憔。

比如撇眯,用where id = 6這個條件時,發(fā)現(xiàn)沒有這個數(shù)據(jù)記錄虱咧,就會鎖仔荛弧(4,7)這個范圍(注意左開右開不包括記錄)腕巡。

3.臨建鎖(Next-key Lock)

鎖定記錄和區(qū)間玄坦,條件范圍查找時,會鎖住記錄和區(qū)間绘沉。Next-key Lock = Record Lock + Gap Lock煎楣;

比如,用where id > 5 and id <9時车伞,就會鎖自穸(4,7]和(7,10]這個范圍的區(qū)間和記錄另玖,也就是(4,10]這個范圍的記錄和區(qū)間(注意是左開右閉困曙,不包括左邊的記錄,包括右邊的記錄)

事務(wù)隔離級別的選擇

首先Read Uncommited不加鎖和Serializable串行化這兩種級別基本是不會被使用的日矫。

Read Commited 對于普通的select語句使用mvcc赂弓,對于加鎖的select和更新語句使用Record Lock記錄鎖绑榴。

Repeatable Read 對于普通的select語句使用mvcc哪轿,對于加鎖的select和更新語句會使用Next-key Lock 、 Record Lock 翔怎、 Gap Lock窃诉。

1.RR的間隙鎖會導(dǎo)致鎖的范圍擴(kuò)大

2.條件列未使用到索引時杨耙,RR鎖表,RC鎖行

3.RC的“半一致性”讀(semi-consistent)可以增加update操作的并發(fā)性飘痛。

從上述三個問題中珊膜,看似RC的級別更有優(yōu)勢,其實(shí)在實(shí)際中宣脉,合理的加鎖车柠,在有索引的列加鎖并不會出現(xiàn)上邊的情況,通常使用默認(rèn)的事務(wù)隔離級別RR就ok了塑猖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竹祷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子羊苟,更是在濱河造成了極大的恐慌塑陵,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜡励,死亡現(xiàn)場離奇詭異令花,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凉倚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門兼都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稽寒,你說我怎么就攤上這事俯抖。” “怎么了瓦胎?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵芬萍,是天一觀的道長。 經(jīng)常有香客問我搔啊,道長柬祠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任负芋,我火速辦了婚禮漫蛔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘旧蛾。我一直安慰自己莽龟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布锨天。 她就那樣靜靜地躺著毯盈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪病袄。 梳的紋絲不亂的頭發(fā)上搂赋,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天赘阀,我揣著相機(jī)與錄音,去河邊找鬼脑奠。 笑死基公,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宋欺。 我是一名探鬼主播轰豆,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼齿诞!你這毒婦竟也來了秒咨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤掌挚,失蹤者是張志新(化名)和其女友劉穎雨席,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吠式,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陡厘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了特占。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糙置。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖是目,靈堂內(nèi)的尸體忽然破棺而出谤饭,到底是詐尸還是另有隱情,我是刑警寧澤懊纳,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布揉抵,位于F島的核電站,受9級特大地震影響嗤疯,放射性物質(zhì)發(fā)生泄漏冤今。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一茂缚、第九天 我趴在偏房一處隱蔽的房頂上張望戏罢。 院中可真熱鬧,春花似錦脚囊、人聲如沸龟糕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讲岁。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間催首,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工泄鹏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郎任,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓备籽,卻偏偏與公主長得像舶治,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子车猬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容