架構(gòu)設(shè)計事務(wù)篇之Mysql事務(wù)原理

avatar

概述

事務(wù)是一組讀寫操作,這些操作被當(dāng)作一個獨立的工作單元被執(zhí)行丈咐,這些操作的執(zhí)行結(jié)果要么全部成功瑞眼,要么全部失敗,不允許部分成功棵逊、部分失敗的情況出現(xiàn)伤疙。
在數(shù)據(jù)庫中,事務(wù)的作用是為了保障數(shù)據(jù)的一致性,即:操作結(jié)果和期望的結(jié)果一致徒像,它有四個特性:原子性黍特、一致性、隔離性锯蛀、持久性灭衷。

實列

事務(wù)最典型的一個例子是轉(zhuǎn)賬,假設(shè)我們有一個賬戶表旁涤,表中有兩條記錄翔曲,一條是A賬戶的記錄其余額為100,另一條是B賬戶的記錄其余額為50劈愚。
這時瞳遍,A賬戶發(fā)起了一筆轉(zhuǎn)賬到B賬戶的請求,其金額為50菌羽;此時該轉(zhuǎn)賬操作便是一個事務(wù)掠械,它包含兩個寫操作,一個是A賬戶扣減50注祖,另一個是B賬戶增加50猾蒂;
這兩個操作是不可分割的,不能出現(xiàn)只執(zhí)行其中一個而不執(zhí)行另一個氓轰,也不能出現(xiàn)其中一個失敗另一個成功婚夫,否則執(zhí)行結(jié)果就和我們期望的結(jié)果不一致。
比如署鸡,A執(zhí)行成功案糙,B執(zhí)行失敗,那么結(jié)果是A賬戶余額為:50靴庆,B賬戶余額還是:50时捌,這樣就和我們業(yè)務(wù)上期望的結(jié)果A為:50、B為:100不一致了炉抒。
兩個操作對應(yīng)的數(shù)據(jù)庫Sql語句如下:


//扣減A賬戶金額
update account set balance=balance-50 where id="A";
//增加B賬戶金額
update account set balance=balance+50 where id="B";

問題

因此奢讨,為了保障事務(wù)的一致性,我們首先要保重的是事務(wù)中的操作要么都成功要么都失敗不能出現(xiàn)其它情況焰薄,而且當(dāng)其中某些操作失敗時拿诸,該事務(wù)中其它成功的操作需要被撤銷使數(shù)據(jù)恢復(fù)到事務(wù)執(zhí)行前的狀態(tài),
這便是我們碰到的第一個問題:需要保證事務(wù)的原子性塞茅。
其次亩码,因為數(shù)據(jù)操作都是先從磁盤加載到內(nèi)存,然后在內(nèi)存進行數(shù)據(jù)更新野瘦,最后同步到磁盤描沟,這就引發(fā)了操作執(zhí)行后數(shù)據(jù)持久性的問題飒泻,即:如何保證事務(wù)成功后重啟數(shù)據(jù)庫后數(shù)據(jù)狀態(tài)還是期望的狀態(tài)。
最后吏廉,因為現(xiàn)代處理器的架構(gòu)都是多核架構(gòu)泞遗,在支持多個事務(wù)并行處理的情況下,如何保證事務(wù)之間不相互影響席覆,這便是事務(wù)之間隔離性的問題史辙,比如說:同一時刻有兩個事務(wù)給B賬戶轉(zhuǎn)賬50,如果兩個事務(wù)在執(zhí)行過程中獲取的賬戶金額都是50娜睛,那么最后的結(jié)果便是100髓霞,而不是150,這就和期望的結(jié)果不一致了畦戒;

所以方库,為了保證數(shù)據(jù)的一致性,我們需要事務(wù)保證其操作執(zhí)行的原子性和隔離性以及操作結(jié)果即數(shù)據(jù)的持久性障斋。

方案

下面我們以最常用的數(shù)據(jù)庫Mysql為例纵潦,講解一下它是通過什么方式保證事務(wù)的原子性、隔離性以及持久性的垃环,從而實現(xiàn)數(shù)據(jù)的一致性邀层。

原子性

原子性所要解決的關(guān)鍵問題是事務(wù)執(zhí)行失敗時,已經(jīng)執(zhí)行成功的操作如何撤銷或者說如何將已經(jīng)被更改的數(shù)據(jù)恢復(fù)到該事務(wù)開始執(zhí)行前的狀態(tài)遂庄。
Mysql使用的是undo日志寥院,事務(wù)開始后,如果要修改某一條記錄涛目,Mysql會先將該記錄的原始值保存在undo日志中并同步到磁盤秸谢,接著才是修改記錄,最后提交事務(wù)霹肝。

比如估蹄,我們只執(zhí)行下面這條Sql語句:

update account set balance=balance-50 where id="A";

那么其事務(wù)實現(xiàn)過程大致如下:

1、開始事務(wù)A
2沫换、將balance原始值100存儲到undo日志中
3臭蚁、將balance修改為50
4、提交事務(wù)

在上面的事務(wù)的執(zhí)行過程中讯赏,如果事務(wù)執(zhí)行到第三步出現(xiàn)了異常垮兑,那么可以通過undo日志恢復(fù)內(nèi)存中的數(shù)據(jù),如果在這之前出現(xiàn)異常什么都不需要做因為日志數(shù)據(jù)和原始數(shù)據(jù)是一致的漱挎。

持久性

持久性所面臨的問題是如何將內(nèi)存中的數(shù)據(jù)高效地同步到磁盤甥角,如上面的例子最簡單的方法就是在第三步后第四步前,將balance寫入磁盤识樱,如下:

1、開始事務(wù)A
2、將balance原始值100存儲到undo日志中
3怜庸、將balance修改為50
4当犯、將balance數(shù)據(jù)寫入磁盤
5、提交事務(wù)

但是割疾,如果存在多條變更的數(shù)據(jù)會因磁盤尋址耗時導(dǎo)致數(shù)據(jù)庫處理事務(wù)的性能變低嚎卫,所以Mysql采用redo日志來順序記錄變更的數(shù)據(jù),這樣減少了不必要的尋址宏榕。
等到拓诸,事務(wù)提交后,Mysql會使異步將redo中的數(shù)據(jù)線程

隔離性

隔離性所面臨的問題是一個事務(wù)在執(zhí)行的過程中是否允許另一個事務(wù)讀取它正在修改的數(shù)據(jù)麻昼,如果不允許那么就得讓事務(wù)串行化奠支,這是最高的隔離級別,如果允許那么又有三種不同的隔離級別:讀未提交抚芦、讀已提交倍谜、可重復(fù)讀绍昂。

讀未提交:一個事務(wù)可以讀取另一個事務(wù)未提交的數(shù)據(jù)梳虽,這種不采取任何隔離措施的策略會導(dǎo)致臟讀殖演、幻讀锦秒、不可重讀等問題力崇,而且對數(shù)據(jù)一致性沒有任何保障瘾婿。

讀已提交:一個事務(wù)可以讀取另一個事務(wù)已經(jīng)提交的數(shù)據(jù)馒胆,它避免了臟讀热康,但還存在幻讀消返、不可重復(fù)讀的問題载弄。

可重復(fù)讀:同個事務(wù)多次讀取相同的數(shù)據(jù)放回的結(jié)果是一樣的,Mysql的可重復(fù)讀可以解決臟讀侦副、幻讀侦锯、不可重讀的問題。

那什么情況下會發(fā)生臟讀秦驯、幻讀尺碰、不可重讀呢?

臟讀發(fā)生在一個事務(wù)A讀取另一個事務(wù)B未提交的數(shù)據(jù)時译隘,如果B最后因為失敗回滾亲桥,那么A讀取的數(shù)據(jù)就是無效的。

幻讀發(fā)生在一個事務(wù)向數(shù)據(jù)庫插入某條數(shù)據(jù)ID為X的記錄是固耘,它先select沒有發(fā)現(xiàn)該記錄题篷,然后準(zhǔn)備插入此時發(fā)現(xiàn)數(shù)據(jù)庫已經(jīng)存在該條記錄,這條記錄是另一個事務(wù)在其select之后提交的厅目。

不可重復(fù)讀發(fā)生在一條記錄被并發(fā)修改番枚,這樣導(dǎo)致會導(dǎo)致某個事務(wù)多次讀取的數(shù)據(jù)結(jié)果不一樣法严。

擴展閱讀

架構(gòu)設(shè)計思維篇之結(jié)構(gòu)

架構(gòu)設(shè)計思維篇之概念

架構(gòu)設(shè)計容錯篇之重試

架構(gòu)設(shè)計容錯篇之熔斷

架構(gòu)設(shè)計容錯篇之限流

架構(gòu)設(shè)計事務(wù)篇之Mysql事務(wù)原理

架構(gòu)設(shè)計事務(wù)篇之CAP定理

架構(gòu)設(shè)計事務(wù)篇之分布式事務(wù)

架構(gòu)設(shè)計消息篇之消息丟失

架構(gòu)設(shè)計消息篇之保證消息順序性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市葫笼,隨后出現(xiàn)的幾起案子深啤,更是在濱河造成了極大的恐慌,老刑警劉巖路星,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溯街,死亡現(xiàn)場離奇詭異,居然都是意外死亡洋丐,警方通過查閱死者的電腦和手機呈昔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來友绝,“玉大人堤尾,你說我怎么就攤上這事【爬疲” “怎么了哀峻?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哲泊。 經(jīng)常有香客問我剩蟀,道長,這世上最難降的妖魔是什么切威? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任育特,我火速辦了婚禮,結(jié)果婚禮上先朦,老公的妹妹穿的比我還像新娘缰冤。我一直安慰自己,他們只是感情好喳魏,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布棉浸。 她就那樣靜靜地躺著,像睡著了一般刺彩。 火紅的嫁衣襯著肌膚如雪迷郑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天创倔,我揣著相機與錄音嗡害,去河邊找鬼。 笑死畦攘,一個胖子當(dāng)著我的面吹牛霸妹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播知押,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叹螟,長吁一口氣:“原來是場噩夢啊……” “哼鹃骂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罢绽,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤偎漫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后有缆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡温亲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年棚壁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栈虚。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡袖外,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出魂务,到底是詐尸還是另有隱情曼验,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布粘姜,位于F島的核電站鬓照,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏孤紧。R本人自食惡果不足惜豺裆,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望号显。 院中可真熱鬧臭猜,春花似錦、人聲如沸押蚤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揽碘。三九已至次屠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钾菊,已是汗流浹背帅矗。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留煞烫,地道東北人浑此。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像滞详,于是被迫代替她去往敵國和親凛俱。 傳聞我的和親對象是個殘疾皇子紊馏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

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