(轉(zhuǎn))談?wù)凪ySQL的事務(wù)隔離級別

這篇文章能夠闡述清楚跟數(shù)據(jù)庫相關(guān)的四個概念:事務(wù)、數(shù)據(jù)庫讀現(xiàn)象禽作、隔離級別尸昧、鎖機制

一、事務(wù)

先來看下百度百科對數(shù)據(jù)庫事務(wù)的定義:

作為單個邏輯單元執(zhí)行一系列操作旷偿,要么完全執(zhí)行烹俗,要么完全不執(zhí)行。事務(wù)處理可以確保除非事務(wù)性單元內(nèi)的所有操作都成功完成萍程,否則不會永久更新面向數(shù)據(jù)的資源幢妄。

事務(wù)有四個屬性,稱為ACID屬性:

1茫负、原子性(Atomicity):事務(wù)是一個原子單位蕉鸳,要么全部執(zhí)行,要么全部不執(zhí)行忍法。

2潮尝、一致性(Consistent):事務(wù)的開始和結(jié)束榕吼,數(shù)據(jù)都必須保持一致狀態(tài)。

3衍锚、隔離性(isolation):數(shù)據(jù)庫系統(tǒng)提供隔離機制友题,保證并發(fā)事務(wù)之間是互相不干擾的。也就意味著事務(wù)處理過程中的中間狀態(tài)對其他的事務(wù)是透明的戴质。

4度宦、持久性(Durable):事務(wù)完成之后,對數(shù)據(jù)的修改是永久性的告匠,即使出現(xiàn)系統(tǒng)故障也能夠保持戈抄。

事務(wù)是一系列SQL語句的集合,如果沒有事務(wù)后专,會出現(xiàn)什么問題划鸽?或者說SQL只能一條一條的單個執(zhí)行,會出現(xiàn)什么問題戚哎?

這個很簡單裸诽,如果沒有事務(wù),我們平時生活中的銀行轉(zhuǎn)賬就無法操作型凳。

二丈冬、數(shù)據(jù)庫讀現(xiàn)象

ACID屬性里面有一個是隔離級別,即并發(fā)事務(wù)之間互相不干擾甘畅」∪铮互相不干擾只是一個終極狀態(tài),且需要消耗巨大的性能疏唾。在我們實際應(yīng)用過程中蓄氧,是存在很大的灰度空間的:隔離級別有程度的區(qū)分。所以如果隔離程度控制的比較弱的話槐脏,就會產(chǎn)生臟讀喉童、不可重復(fù)讀以及幻讀的現(xiàn)象。

1准给、臟讀

事務(wù)T1修改某個字段的值泄朴,然后事務(wù)T2讀取該值,此后T1撤銷了對該字段的更新露氮,或者更新成另外的值才commit到數(shù)據(jù)庫中祖灰,這樣T2讀取的數(shù)據(jù)是無效的或者錯誤的。導(dǎo)致T2依據(jù)臟數(shù)據(jù)所做的操作也是錯誤的畔规。

思聰同學(xué)中午去食堂吃飯局扶,看到窗邊的座位被如花同學(xué)占有了,思聰認為這個座位已經(jīng)被占有了,就轉(zhuǎn)身去找其他的座位三妈。不料畜埋,如花同學(xué)起身離開了。事實是:如花并不是吃飯畴蒲,而是臨時坐在那里等她的約會對象悠鞍,只是臨時小坐一會,并沒有真正“commit”模燥。

2咖祭、不可重復(fù)讀

在數(shù)據(jù)庫訪問中,一個事務(wù)范圍內(nèi)的兩次相同的查詢卻返回了不同的數(shù)據(jù)蔫骂。

事務(wù)T1讀取某一數(shù)據(jù)么翰,事務(wù)T2讀取并修改了該數(shù)據(jù),T1為了對讀取值進行驗證而重新讀取辽旋,卻發(fā)現(xiàn)得到了不同的結(jié)果浩嫌。

思聰同學(xué)中午去食堂吃飯,看到窗邊的座位是空的补胚,便屁顛屁顛的跑去打飯码耐,回來后卻發(fā)現(xiàn)這個座位被如花同學(xué)搶去了。

3溶其、幻讀

幻讀解決了不可重復(fù)讀的問題伐坏,即在同一個事務(wù)范圍內(nèi),兩次相同的查詢結(jié)果是相同的握联。但是可以新增表中的數(shù)據(jù)記錄。

幻讀是指事務(wù)T1對表中的數(shù)據(jù)進行修改每瞒,假設(shè)修改涉及了表中全部的數(shù)據(jù)行金闽,同時第二個事務(wù)也修改這個表中的數(shù)據(jù),這種修改是向表中插入一條新的數(shù)據(jù)剿骨。后面就會出現(xiàn)操作了T1事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行代芜,仿佛出現(xiàn)了幻覺一樣。

思聰同學(xué)中午去食堂吃飯浓利,看到窗邊的座位是空的挤庇,便屁顛屁顛的跑去打飯,回來后窗邊的座位還是空的贷掖,便很高興坐上去準(zhǔn)備開始吃飯嫡秕,這時候卻發(fā)現(xiàn)如花同學(xué)搬了一個小板凳坐在旁邊狼吞虎咽,思聰頓時沒有了胃口苹威。

如果需要解決臟讀昆咽、不可重復(fù)讀、幻讀等這些數(shù)據(jù)庫讀現(xiàn)象,就必須相應(yīng)提高事務(wù)的隔離級別掷酗。但是數(shù)據(jù)庫的隔離級別越高调违,對應(yīng)的并發(fā)能力就越弱,性能也就相應(yīng)的越差泻轰,所以我們還需根據(jù)具體的應(yīng)用場景去權(quán)衡技肩。

三、事務(wù)隔離級別

1浮声、未提交讀

事務(wù)的最低隔離級別虚婿,在這種隔離級別下,一個事務(wù)可以讀取另外一個事務(wù)未提交的數(shù)據(jù)阿蝶。

數(shù)據(jù)庫鎖實現(xiàn)原理:

事務(wù)T在讀數(shù)據(jù)的時候并未對數(shù)據(jù)進行加鎖雳锋,事務(wù)T在修改數(shù)據(jù)的時候?qū)?shù)據(jù)增加行級共享鎖

T1在讀取數(shù)據(jù)時,T2可以對相同數(shù)據(jù)進行讀取羡洁、修改玷过。因為T1沒有進行任何鎖操作;當(dāng)T2對記錄進行修改時筑煮,T1再次讀取數(shù)據(jù)可以讀取到T2修改后的數(shù)據(jù)辛蚊。因為T2對數(shù)據(jù)進行修改只增加了行級共享鎖,T1可以再增加共享讀鎖進行數(shù)據(jù)讀日嬷佟(盡管T2沒有提交事務(wù))

如上所述袋马,這種隔離級別,會導(dǎo)致臟讀現(xiàn)象

2秸应、已提交讀

在一個事務(wù)修改數(shù)據(jù)過程中虑凛,如果事務(wù)沒有進行提交,其他事務(wù)不能讀取該數(shù)據(jù)

數(shù)據(jù)庫鎖實現(xiàn)原理:

事務(wù)T在讀取數(shù)據(jù)時增加行級共享鎖软啼,讀取一旦結(jié)束桑谍,立即釋放;事務(wù)T在修改數(shù)據(jù)時增加行級排他鎖祸挪,直到事務(wù)結(jié)束才釋放锣披。

T1在讀取數(shù)據(jù)的過程中,T2也可以對相同數(shù)據(jù)進行讀取贿条,但是不能進行修改(T1增加的是共享鎖雹仿,T2也可以增加共享鎖,但是不能增加排他鎖)整以。T1讀取結(jié)束后胧辽,會立即釋放共享鎖,這時T2可以增加排他鎖悄蕾,對數(shù)據(jù)進行修改票顾,而此時T1既不能對數(shù)據(jù)進行讀取也不能進行修改础浮,直到T2事務(wù)結(jié)束。

如上所述奠骄,這種隔離級別豆同,解決了臟讀問題,但是不能解決不可重復(fù)讀現(xiàn)象含鳞。

3影锈、可重復(fù)讀

事務(wù)T在數(shù)據(jù)讀取時,必須增加行級共享鎖蝉绷,直到事務(wù)結(jié)束鸭廷;事務(wù)T在修改數(shù)據(jù)過程中,必須增加行級排他鎖熔吗,直到數(shù)據(jù)結(jié)束辆床。

數(shù)據(jù)庫鎖實現(xiàn)原理:

T1在讀取數(shù)據(jù)的過程中,T2也可以對相同數(shù)據(jù)進行讀取桅狠,但是不能進行修改(T1增加的是共享鎖讼载,T2也可以增加共享鎖,但是不能增加排他鎖)中跌。直到T1事務(wù)結(jié)束后咨堤,才會釋放共享鎖,這時T2才可以增加排他鎖漩符,對數(shù)據(jù)進行修改一喘。

如上所述,這種隔離級別嗜暴,解決了不可重復(fù)讀現(xiàn)象凸克,但是這種隔離級別解決不了幻讀的問題:

T1進行查詢,讀取了10條記錄闷沥,并對十條記錄增加了行級鎖触徐,此時T2是無法對這10行數(shù)據(jù)進行修改操作的,但是由于沒有表級鎖狐赡,它可以增加一條滿足T1查詢條件的記錄。隨后T1在進行查詢時疟丙,會發(fā)現(xiàn)雖然10條記錄沒有改變颖侄,但是突然多了一條記錄。

4享郊、序列化

產(chǎn)生幻讀是由于沒有進行范圍查詢時沒有增加范圍鎖览祖。

數(shù)據(jù)庫鎖實現(xiàn)原理:

** 事務(wù)T在讀取數(shù)據(jù)時,必須先增加表級共享鎖炊琉,直到事務(wù)結(jié)束才釋放展蒂;事務(wù)T在修改數(shù)據(jù)時又活,必須先增加表級排他鎖,直到事務(wù)結(jié)束才釋放锰悼。**

T1在讀取A表時柳骄,增加了表級共享鎖,此時T2也可以讀取A表箕般,但是不能進行任何數(shù)據(jù)的修改耐薯,直到T1事務(wù)結(jié)束。隨后T2可以增加對A表的表級排他鎖丝里,此時T1不能讀取A表中的任何數(shù)據(jù)曲初,更不能進行修改。

如上所述杯聚,可序列化解決了臟讀臼婆、不可重復(fù)讀、幻讀等讀現(xiàn)象幌绍,但是隔離級別越來越高的同時颁褂,在并發(fā)性上也就越來越低。

**四纷捞、事務(wù)操作實踐 **

默認情況下痢虹,MYSQL是自動提交的,也就意味著平時我們執(zhí)行一條update語句時主儡,MYSQL是自動幫我們提交的奖唯,盡快我們沒有顯示執(zhí)行commit命令。但是這種只適用于單條SQL的執(zhí)行糜值。

如果我們想要同時執(zhí)行多條SQL丰捷,并且執(zhí)行過程中有SQL執(zhí)行異常,需要回滾前面已經(jīng)成功執(zhí)行的SQL或者最終想回滾全部寂汇,則必須顯示的使用事務(wù)病往。

  1. 開始一項事務(wù):start tr ansaction或者begin;

  2. 提交事務(wù):commit骄瓣;

  3. 回滾事務(wù):rollback停巷;

  4. 事務(wù)提交之后的操作:chain;

  5. 事務(wù)回滾之后的操作:release榕栏;

  6. 修改當(dāng)前連接的提交方式:set autocommit畔勤;如果設(shè)置了set autocommit=0,則設(shè)置之后所有的事務(wù)都需要顯式的通過命令來進行提交或者回滾扒磁。

查詢當(dāng)前會話的事務(wù)隔離級別

images/2pyKrnNwf5pC2F3eBa8A8K3DzBZ2azxA.png

查詢當(dāng)前系統(tǒng)的事務(wù)隔離級別

images/DZYPrwHrsK5x5dK4STHQceX2h6iSNDd3.png

修改當(dāng)前會話的事務(wù)隔離級別

images/7Yr4k8krs5naMHn3TciejMjmdxBWRNmH.png

提交讀演示

客戶端A 開啟事務(wù)庆揪,并更新數(shù)據(jù)

images/CtxNtjBJCaPHHK3PmxX4xYydWcenNkZY.png

此時事務(wù)還沒有提交,開啟客戶端B妨托,并進行查詢缸榛,此時的數(shù)據(jù)還是未更新前的

images/2B5FcAmzZ3JWHJs2hX3ZT5WRKDA7DRkN.png

客戶端A進行事務(wù)提交吝羞,然后客戶端B查詢,此時是最新的數(shù)據(jù)

images/3ftrb2wN2Yn8Db3AYwBHxd5JmQJsHSap.png

commit and chain的演示

如果在提交的時候使用commit and chain内颗,那么在提交后立即開始一個新的事務(wù)

images/R5GMDSkjiZRWx4DmcZ7zQ74TQMn8HKex.png

A提交事務(wù)后钧排,B再進行查詢

images/3kzdQD32SbywQWxffJBScSWR6wRPxwys.png

開啟事務(wù)會隱式解鎖

鎖表期間,用start transaction 命令開始一個新事務(wù)起暮,則會隱式的執(zhí)行unlock tables

A對表進行寫鎖操作

images/ZKzxAfyfAHfT5Z823rHirYamFRMbhMJQ.png

此時B進行查詢:由于被A鎖表辱士,所以查詢被阻塞

images/yWSc7PWzPSJTNwBBB8D4ZwbCFeYyK5JT.png

A開啟一個事務(wù)

images/73kdSd5QfJRJa7XtsaH7bkictpYGf3Hm.png

由于A開啟事務(wù)正塌,隱式的釋放了寫鎖半等,所以B的查詢不再被阻塞

images/5KnEJPYmXTE6TNF2ytyDnf4TspXRmAfr.png

SAVEPOINT的使用

事務(wù)中可以通過定義SAVEPOINT缩滨,指定回滾事務(wù)的一個部分
A開啟事務(wù)并insert一條記錄,并設(shè)置savepoint

images/8KnAAhkGr5aH8bh2k28ySfH7PemQZEyc.png

B進行查詢纸厉,查詢到的是開啟事務(wù)前的數(shù)據(jù)

images/JyWNj2fPb6iEbbdzcTi6bQr8mBfE6zt8.png

A又插入一條數(shù)據(jù)系吭,然后回滾到savepoint

images/QsjcpfTa3zy6math65hXSd8hHfE6dbSY.png
images/tfDMCMA4CP4ijB6f7BCd4FN7yhGhtSZY.png

B進行查詢

images/tx2tJmcCRzbBf8Pyp5n6NMkSmGyXmBC8.png
作者:冬瓜蔡原文:http://www.cnblogs.com/dongguacai/p/7114885.html
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颗品,隨后出現(xiàn)的幾起案子肯尺,更是在濱河造成了極大的恐慌,老刑警劉巖躯枢,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件则吟,死亡現(xiàn)場離奇詭異,居然都是意外死亡锄蹂,警方通過查閱死者的電腦和手機氓仲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來得糜,“玉大人敬扛,你說我怎么就攤上這事〕叮” “怎么了啥箭?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長治宣。 經(jīng)常有香客問我急侥,道長,這世上最難降的妖魔是什么侮邀? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任缆巧,我火速辦了婚禮,結(jié)果婚禮上豌拙,老公的妹妹穿的比我還像新娘。我一直安慰自己题暖,他們只是感情好按傅,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布捉超。 她就那樣靜靜地躺著,像睡著了一般唯绍。 火紅的嫁衣襯著肌膚如雪拼岳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天况芒,我揣著相機與錄音惜纸,去河邊找鬼。 笑死绝骚,一個胖子當(dāng)著我的面吹牛耐版,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播压汪,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粪牲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了止剖?” 一聲冷哼從身側(cè)響起腺阳,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎穿香,沒想到半個月后亭引,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡皮获,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年焙蚓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魔市。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡主届,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出待德,到底是詐尸還是另有隱情君丁,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布将宪,位于F島的核電站绘闷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏较坛。R本人自食惡果不足惜印蔗,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丑勤。 院中可真熱鬧华嘹,春花似錦、人聲如沸法竞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至薛躬,卻和暖如春俯渤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背型宝。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工八匠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趴酣。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓梨树,卻偏偏與公主長得像,于是被迫代替她去往敵國和親价卤。 傳聞我的和親對象是個殘疾皇子劝萤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

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