數(shù)據(jù)庫隔離級別的理解

文章初衷

最開始聽到隔離級別這個詞是在大學上數(shù)據(jù)庫課的時候老師講到却邓,當時聽得一頭霧水最終也沒理解到耿芹,就不了了之了怠硼。到畢業(yè)開始找工作,每次面試前的知識點整理私沮,總能看到隔離級別這個詞始赎,但是每次都停留在背書式的記住。一直對隔離級別這個詞感覺很陌生甚至有點抗拒仔燕。最近公司在做技術(shù)分享造垛,我想分享一下MVCC的理解,在查資料的過程中發(fā)現(xiàn)MVCC 跟 隔離級別晰搀、undo log等知識點關(guān)聯(lián)還是很密切的五辽,所以也順便系統(tǒng)的去學習一下隔離級別。

開始正題

我對隔離級別的理解:事務之間互相影響的程度外恕。比如在A事務中需要查詢和修改用戶余額字段奔脐,現(xiàn)在進來了一個B事務也改動了用戶余額的字段,隔離級別就規(guī)定B事務的改動對A事務的影響程度吁讨。

不同的隔離級別導致 A髓迎、B兩個事務之間的操作有不同的影響。

隔離級別可以理解為處理多事務并發(fā)操作數(shù)據(jù)時的不同策略建丧。下面先列出多事務并發(fā)操作可能引起的問題排龄。

ANSI/ISO SQL 定義了 4 種標準隔離級別。
下面根據(jù)隔離程度從低到高分別說明。

讀未提交(Read uncommitted)

這個隔離級別規(guī)定:在查詢數(shù)據(jù)時能讀取到未提交事務中修改了的數(shù)據(jù)結(jié)果橄维。

字面上理解起來可能比較難尺铣,我們直接來看例子:

時間點 事務A 事務B
T1 開啟事務
T2 開啟事務
T3 查詢余額,結(jié)果是100
T4 修改余額為150
T5 查詢余額争舞,結(jié)果是150
T6 提交事務
T7 提交事務

上面例子可以看到困后,事務B在修改了余額后,事務A能馬上查詢到修改后的結(jié)果创译。這就是 讀未提交 的效果酒唉,結(jié)合上面這個例子去理解的話,讀未提交就是:事務A能 事務B 未提交 的數(shù)據(jù)委乌。

這個隔離級別會產(chǎn)生一個問題床牧。假如事務B最終沒有提交事務,而是回滾了遭贸「昕龋可以看一下下面這個例子:

時間點 事務A 事務B
T1 開啟事務
T2 開啟事務
T3 查詢余額,結(jié)果是100
T4 修改余額為150
T5 查詢余額壕吹,結(jié)果是150
T6 事務回滾
T7 查詢余額著蛙,結(jié)果是100
T8 提交事務

由于事務B最終回滾了,事務A在 時間點T4 拿到的余額150是一個臟數(shù)據(jù)耳贬,我們稱這個問題為:臟讀册踩。

總結(jié)來說,在讀未提交隔離級別下效拭,數(shù)據(jù)的改動能實時的被查詢出來暂吉,這帶來的問題是會出現(xiàn) 臟讀。

讀已提交(Read commited)

理解了上面的讀未提交缎患,再來看讀已提交的話應該就比較好理解了慕的。

讀已提交隔離級別規(guī)定:只有在事務提交后,事務中修改了的數(shù)據(jù)才能被其他事務查詢到挤渔。

我們還是來看一下例子:

時間點 事務A 事務B
T1 開啟事務
T2 開啟事務
T3 查詢余額肮街,結(jié)果是100
T4 修改余額為150
T5 查詢余額,結(jié)果是100
T6 提交事務
T7 查詢余額判导,結(jié)果是150
T8 提交事務

根據(jù)上面這個例子可以看到嫉父,事務B 在 時間點T4 修改了余額但未提交事務,事務A 在 T5 查詢余額時眼刃,是查不到事務B修改過的余額绕辖。在事務B 提交事務后,事務A再去查詢余額擂红,就能拿到事務B 修改后的余額仪际。

結(jié)合這個例子去理解的話,讀已提交就是:事務A能 事務B 已提交 的數(shù)據(jù)。

這個隔離級別不會出現(xiàn)臟讀树碱,但會有另外的問題肯适。可以看回上面的例子成榜,事務A 對余額做了多次查詢框舔,卻得到了不同的結(jié)果,在我們實現(xiàn)部分業(yè)務邏輯時這可能是一個不正常的現(xiàn)象赎婚。因為重復讀同一條數(shù)據(jù)會得到不同的結(jié)果刘绣,所以我們稱這個問題為:不可重復讀

總結(jié)來說惑淳,在讀已提交隔離級別下额港,數(shù)據(jù)的改動在事務提交后能實時的被查詢出來饺窿,這帶來的問題是會出現(xiàn) 不可重復讀歧焦。

可重復讀(Repeatable read)

這個隔離級別名稱我認為是比較抽象的。由于這個隔離級別解決了 讀已提交 產(chǎn)生的不可重復讀問題肚医,所以這個隔離級別就叫 可重復讀绢馍。

可重復讀隔離級別規(guī)定:事務只能查詢到事務開始之前已提交的數(shù)據(jù)。

我們還是通過具體例子來說明:

時間點 事務A 事務B 事務C
T1 開啟事務
T2 開啟事務
T3 查詢余額肠套,結(jié)果是100
T4 修改余額為150
T5 查詢余額舰涌,結(jié)果是100
T6 提交事務
T7 查詢余額,結(jié)果是100
T8 開始事務
T9 查詢余額你稚,結(jié)果是150
T10 提交事務
T11 提交事務

事務B 在事務A 開始之后才開始瓷耙,所以事務B的更新操作不會影響到事務A 的查詢,即使事務B提交了刁赖,事務A還是拿到余額100的結(jié)果搁痛。事務C 在事務B 提交之后才開始,所以事務C 能查到事務B 修改后的結(jié)果宇弛。

可以看到事務A每次查詢都能得到同樣的結(jié)果鸡典,這解決了 讀已提交 的不可重復讀問題。

但這個隔離級別還是存在另外一個問題:幻讀枪芒。我認為 幻讀 這個問題是最難理解的彻况,我們先來看一下例子:

假設(shè)我們現(xiàn)在表中有兩條數(shù)據(jù):

id account balance
1 張三 1000
2 李四 2000

然后我們進行以下操作

時間點 事務A 事務B
T1 開啟事務
T2 開啟事務
T3 新增一個王五的賬號,余額3000
T4 提交事務
T5 查詢列表舅踪,返回 張三纽甘、李四 兩條數(shù)據(jù)
T6 更新王五的余額
T7 查詢列表,返回 張三抽碌、李四贷腕、王五 三條數(shù)據(jù)
T8 提交事務

上面例子時間點 T5,T6,T7 看上去很詭異,但是實際操作的確也是得到這樣的結(jié)果。我是這樣理解的:

  1. 事務A 在 T5 查詢不到王五的數(shù)據(jù)泽裳,那是因為事務B在事務A之后開始瞒斩,這里滿足 可重復讀 隔離級別的規(guī)則。
  2. T6 能更新王五這條數(shù)據(jù)應該是最讓人迷惑的涮总。但其實我們細想一下胸囱,這里是事務A 的更新操作,而我們之前談到的隔離級別都是講的select操作瀑梗。在這里事務A 通過select語句的確是查詢不到事務A 的數(shù)據(jù)烹笔,但是update 操作根據(jù)where其實是能找到這一條數(shù)據(jù)的∨桌觯可以理解為谤职,select的查詢與update中where查詢是不一樣邏輯。
  3. T7 這時候能查到王五這一條數(shù)據(jù)亿鲜,是因為T6 對王五做了更新操作允蜈,導致王五這條數(shù)據(jù)存在一個事務A操作過的版本≥锪可重復讀隔離級別下饶套,是允許查詢到當前事務中修改過的數(shù)據(jù),所以事務A 這里查得到王五這條數(shù)據(jù)也是符合可重復讀隔離級別的垒探。

上面這個例子妓蛮,一開始我們查詢列表只有2條數(shù)據(jù),后來又查到3條數(shù)據(jù)圾叼,這就是我們上面提到的 幻讀蛤克。

幻讀 與 不可重復讀 有那么一點相像,兩者都是在用相同條件多次查詢時得到不同的結(jié)果夷蚊。我的理解是构挤,不可重復讀更側(cè)重于數(shù)據(jù)內(nèi)容的變更,而幻讀側(cè)重于由于事務內(nèi)的一些操作導致本來查詢不到的數(shù)據(jù)變成對當前事務可見撬码。

串行化(Serializable)

這是最嚴謹?shù)母綦x級別儿倒,為了不因為多事務并行執(zhí)行導致數(shù)據(jù)的不一致,直接規(guī)定事務串行去執(zhí)行呜笑。就是上一個事務未結(jié)束夫否,下一個事務不會開始。串行化比較好理解叫胁,就不做舉例了凰慈。

前面提到的3種問題(臟讀、不可重復度驼鹅、幻讀)在串行化隔離級別下微谓,都不會發(fā)生森篷,所以說這個是最嚴謹?shù)母綦x級別。


隔離級別越高豺型,需要消耗的性能越多仲智。

MySQL InnoDB引擎默認使用 可重復讀 隔離級別

這里額外說一點,讀已提交姻氨、可重復讀 這兩個隔離級別的數(shù)據(jù)其實是比較特別的钓辆。我們再拿可重復讀中的例子來看一下:

時間點 事務A 事務B 事務C
T1 開啟事務
T2 開啟事務
T3 查詢余額,結(jié)果是100
T4 修改余額為150
T5 查詢余額肴焊,結(jié)果是100
T6 提交事務
T7 查詢余額前联,結(jié)果是100
T8 開始事務
T9 查詢余額,結(jié)果是150
T10 提交事務
T11 提交事務

這個例子中娶眷,事務A查到的余額一直是100似嗤,而事務B在修改余額后,事務B查詢余額結(jié)果會是150届宠。不知道大家在這里會不會產(chǎn)生疑問烁落,同一個賬戶的余額,事務A查的到是100席揽,事務B查到的是150顽馋,那數(shù)據(jù)庫中這個賬戶的余額字段存的究竟是存的100還是150谓厘?還是100和150余額同時存在于數(shù)據(jù)庫幌羞?這其實是一個叫做 多版本并發(fā)控制 的知識點,又稱作 MVCC(Multi-Version Concurrency Control)竟稳。上面例子中属桦,余額為100和150 的數(shù)據(jù)是同時存在的,這就是多版本的意思他爸。具體的 MVCC介紹留到下一篇文章再說了聂宾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市诊笤,隨后出現(xiàn)的幾起案子系谐,更是在濱河造成了極大的恐慌,老刑警劉巖讨跟,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纪他,死亡現(xiàn)場離奇詭異,居然都是意外死亡晾匠,警方通過查閱死者的電腦和手機茶袒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凉馆,“玉大人薪寓,你說我怎么就攤上這事亡资。” “怎么了向叉?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵锥腻,是天一觀的道長。 經(jīng)常有香客問我母谎,道長旷太,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任销睁,我火速辦了婚禮供璧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冻记。我一直安慰自己睡毒,他們只是感情好,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布冗栗。 她就那樣靜靜地躺著演顾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隅居。 梳的紋絲不亂的頭發(fā)上钠至,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音胎源,去河邊找鬼棉钧。 笑死,一個胖子當著我的面吹牛涕蚤,可吹牛的內(nèi)容都是我干的宪卿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼万栅,長吁一口氣:“原來是場噩夢啊……” “哼佑钾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烦粒,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤休溶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扰她,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兽掰,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年义黎,在試婚紗的時候發(fā)現(xiàn)自己被綠了禾进。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡廉涕,死狀恐怖泻云,靈堂內(nèi)的尸體忽然破棺而出艇拍,到底是詐尸還是另有隱情,我是刑警寧澤宠纯,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布卸夕,位于F島的核電站,受9級特大地震影響婆瓜,放射性物質(zhì)發(fā)生泄漏快集。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一廉白、第九天 我趴在偏房一處隱蔽的房頂上張望个初。 院中可真熱鬧,春花似錦猴蹂、人聲如沸院溺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽珍逸。三九已至,卻和暖如春聋溜,著一層夾襖步出監(jiān)牢的瞬間谆膳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工撮躁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留漱病,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓馒胆,卻偏偏與公主長得像缨称,于是被迫代替她去往敵國和親凝果。 傳聞我的和親對象是個殘疾皇子祝迂,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

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