五分鐘搞清楚MySQL事務(wù)隔離級別

好久沒碰數(shù)據(jù)庫了识藤,只是想起自己當(dāng)時在搞數(shù)據(jù)庫的時候在事務(wù)隔離級別這塊老是卡眯牧,似懂非懂的。現(xiàn)在想把這塊整理出來剪个,盡量用最簡潔的語言描述出來版确,供新人參考。

首先創(chuàng)建一個表account绒疗。創(chuàng)建表的過程略過(由于InnoDB存儲引擎支持事務(wù),所以將表的存儲引擎設(shè)置為InnoDB)惕虑。表的結(jié)構(gòu)如下:

表結(jié)構(gòu)

然后往表中插入兩條數(shù)據(jù),插入后結(jié)果如下:

數(shù)據(jù)

為了說明問題健提,我們打開兩個控制臺分別進(jìn)行登錄來模擬兩個用戶(暫且成為用戶A和用戶B吧)伟叛,并設(shè)置當(dāng)前MySQL會話的事務(wù)隔離級別。

一. read uncommitted(讀取未提交數(shù)據(jù))

具體用戶A的操作如下:

set session transaction isolation level read uncommitted紊遵;
start transaction;
select * from account;

結(jié)果如下:

數(shù)據(jù)

用戶B的操作如下:

set session transaction isolation level read uncommitted暗膜;
start transaction;
update account set account=account+200 where id = 1;

隨后我們在A用戶中查詢數(shù)據(jù)鞭衩,結(jié)果如下:

uncommittedA數(shù)據(jù)

結(jié)論一:

我們將事務(wù)隔離級別設(shè)置為read uncommitted,即便是事務(wù)沒有commit恒水,但是我們?nèi)匀荒茏x到未提交的數(shù)據(jù)饲齐,這是所有隔離級別中最低的一種。

那么這么做有什么問題嗎御雕?

那就是我們在一個事務(wù)中可以隨隨便便讀取到其他事務(wù)未提交的數(shù)據(jù)滥搭,這還是比較麻煩的,我們叫臟讀闽坡。我不知道這個名字是怎么起的愁溜,為了增強(qiáng)大家的印象,可以這么想冕象,這個事務(wù)好輕浮啊,饑渴到連別人沒提交的東西都等不及论悴,真臟,呸膀估!

實際上我們的數(shù)據(jù)改變了嗎?

答案是否定的,因為只有事務(wù)commit后才會更新到數(shù)據(jù)庫齐饮。

二. read committed(可以讀取其他事務(wù)提交的數(shù)據(jù))---大多數(shù)數(shù)據(jù)庫默認(rèn)的隔離級別

同樣的辦法,我們將用戶B所在的會話當(dāng)前事務(wù)隔離級別設(shè)置為read commited握恳。

在用戶A所在的會話中我們執(zhí)行下面操作:

update account set account=account-200 where id=1;
read committed

我們將id=1的用戶account減200乡洼。然后查詢,發(fā)現(xiàn)id=1的用戶account變?yōu)?00束昵。

在B用戶所在的會話中查詢:

select * from account葛峻;

結(jié)果如下:

read committedB

我們會發(fā)現(xiàn)數(shù)據(jù)并沒有變术奖,還是1000。

接著在會話A中我們將事務(wù)提交:

commit;

在會話B中查詢結(jié)果如下:

read committedB1

結(jié)論二:

當(dāng)我們將當(dāng)前會話的隔離級別設(shè)置為read committed的時候佣耐,當(dāng)前會話只能讀取到其他事務(wù)提交的數(shù)據(jù)唧龄,未提交的數(shù)據(jù)讀不到。

那么這么做有什么問題嗎掖鱼?

那就是我們在會話B同一個事務(wù)中援制,讀取到兩次不同的結(jié)果。這就造成了不可重復(fù)讀晨仑,就是兩次讀取的結(jié)果不同拆檬。這種現(xiàn)象叫不可重復(fù)讀竟贯。

三. repeatable read(可重讀)---MySQL默認(rèn)的隔離級別

現(xiàn)在有個需求逝钥,就是老板說在同一個事務(wù)中查詢結(jié)果必須保持一致,如果你是數(shù)據(jù)庫持际,你會怎么做?數(shù)據(jù)庫是這么做的蜘欲。

在會話B中我們當(dāng)前事務(wù)隔離級別為repeatable read晌柬。具體操作如下:

set session transaction isolation level repeatable read;
start transaction;

接著在會話B中查詢數(shù)據(jù):

repeatablereadB1

我們在A用戶所在會話中為表account添加一條數(shù)據(jù):

insert into account(id,account) value(3,1000);
commit;

然后我們查詢看數(shù)據(jù)插入是否成功:

repeatable readA

回到B用戶所在的會話年碘,我們查詢結(jié)果:

repeatablereadB2

用戶B在他所在的會話中想插入一條新數(shù)據(jù)id=3,value=1000闷祥。來我們操作下:

readpeatablereadB3

什么傲诵?竟然插不進(jìn)去,說我數(shù)據(jù)重復(fù)拴竹?

用戶B當(dāng)然不服啊,因為查詢到數(shù)據(jù)只有兩條啊座泳,為什么插入id=3說我數(shù)據(jù)重復(fù)了呢幕与?

我再看一遍,莫非我眼花了啦鸣?

repeatablereadB2

試想一下,在實際中用戶A和用戶B肯定是相互隔離的香拉,彼此不知道操作什么。用戶B碰到這種現(xiàn)象凫碌,肯定會炸毛的啊,明明不存在的數(shù)據(jù)瞄摊,插入?yún)s說主鍵id=3數(shù)據(jù)重復(fù)了苦掘。

結(jié)論三:

當(dāng)我們將當(dāng)前會話的隔離級別設(shè)置為repeatable read的時候,當(dāng)前會話可以重復(fù)讀鸟蜡,就是每次讀取的結(jié)果集都相同揉忘,而不管其他事務(wù)有沒有提交端铛。

有什么問題嗎?

管他呢禾蚕,老板的要求滿足了。要一個事務(wù)中讀取的數(shù)據(jù)一致(可重復(fù)讀)哗总。我只能這么做啊倍试,打腫臉裝胖子。數(shù)據(jù)已經(jīng)發(fā)生改變县习,但是我還是要保持一致。但是叛本,出現(xiàn)了用戶B面對的問題,這種現(xiàn)象叫幻讀(記得當(dāng)時就在這個地方糾結(jié)好久来候,到底什么是幻讀耙荼ⅰ)性芬。

四. serializable(串行化)

同樣植锉,我們將用戶B所在的會話的事務(wù)隔離級別設(shè)置為serializable并開啟事務(wù)。

set session transaction isolation level serializable;
start transaction;

在用戶B所在的會話中我們執(zhí)行下面操作:

select * from account;

結(jié)果如下:

serializableA

那我們這個時候在用戶A所在的會話中寫數(shù)據(jù)呢俊庇?


readcommittedA1

我們發(fā)現(xiàn)用戶A所在的會話陷入等待辉饱,如果超時(這個時間可以進(jìn)行配置)拣展,會出現(xiàn)Lock wait time out提示:

readcommittedA2

如果在等待期間我們用戶B所在的會話事務(wù)提交备埃,那么用戶A所在的事務(wù)的寫操作將提示操作成功。

結(jié)論四:

當(dāng)我們將當(dāng)前會話的隔離級別設(shè)置為serializable的時候按脚,其他會話對該表的寫操作將被掛起∥ň冢可以看到,這是隔離級別中最嚴(yán)格的介蛉,但是這樣做勢必對性能造成影響溶褪。所以在實際的選用上,我們要根據(jù)當(dāng)前具體的情況選用合適的竿滨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末于游,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贰剥,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凛捏,死亡現(xiàn)場離奇詭異坯癣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)示罗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門芝硬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绍绘,你說我怎么就攤上這事迟赃。” “怎么了捺氢?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵摄乒,是天一觀的道長残黑。 經(jīng)常有香客問我,道長梨水,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任舅世,我火速辦了婚禮奇徒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罢低。我一直安慰自己,他們只是感情好网持,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著萍倡,像睡著了一般日杈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酿炸,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天涨冀,我揣著相機(jī)與錄音,去河邊找鬼鹿鳖。 笑死,一個胖子當(dāng)著我的面吹牛姻檀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绣版,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杂抽,長吁一口氣:“原來是場噩夢啊……” “哼韩脏!你這毒婦竟也來了缩麸?” 一聲冷哼從身側(cè)響起杭朱,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弧械,沒想到半個月后送浊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唁桩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了报辱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片单山。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡碍现,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出米奸,到底是詐尸還是另有隱情昼接,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布悴晰,位于F島的核電站慢睡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏铡溪。R本人自食惡果不足惜漂辐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棕硫。 院中可真熱鬧髓涯,春花似錦、人聲如沸哈扮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实檀。三九已至,卻和暖如春恬吕,著一層夾襖步出監(jiān)牢的瞬間铐料,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膝捞,地道東北人愧沟。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓林艘,卻偏偏與公主長得像混坞,于是被迫代替她去往敵國和親拔第。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

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