MySQL 事務(wù)的四種隔離級別

MySQL 事務(wù)的四種隔離級別

1 事務(wù)的基本要素(ACID)

原子性(Atomicity):事務(wù)開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環(huán)節(jié)。事務(wù)執(zhí)行過程中出錯(cuò),會回滾到事務(wù)開始前的狀態(tài),所有的操作就像沒有發(fā)生一樣。也就是說事務(wù)是一個(gè)不可分割的整體,就像化學(xué)中學(xué)過的原子,是物質(zhì)構(gòu)成的基本單位。

一致性(Consistency):事務(wù)開始前和結(jié)束后,數(shù)據(jù)庫的完整性約束沒有被破壞 。比如A向B轉(zhuǎn)賬,不可能A扣了錢,B卻沒收到。

隔離性(Isolation):同一時(shí)間,只允許一個(gè)事務(wù)請求同一數(shù)據(jù),不同的事務(wù)之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結(jié)束前,B不能向這張卡轉(zhuǎn)賬。

持久性(Durability):事務(wù)完成后,事務(wù)對數(shù)據(jù)庫的所有更新將被保存到數(shù)據(jù)庫,不能回滾。

2 事務(wù)的并發(fā)問題

臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)

不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過程中,對數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致。

幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫中所有學(xué)生的成績從具體分?jǐn)?shù)改為ABCDE等級,但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒有改過來,就好像發(fā)生了幻覺一樣,這就叫幻讀。

小結(jié):不可重復(fù)讀的和幻讀很容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除。解決不可重復(fù)讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表

3 事務(wù)的四種隔離級別

隔離級別臟讀(Dirty Read)不可重復(fù)讀(NonRepeatable Read)幻讀(Phantom Read)

讀未提交(Read uncommitted)可能可能可能

讀已提交(Read committed)不可能可能可能

可重復(fù)讀(Repeatable read)不可能不可能可能

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

未提交讀(Read Uncommitted):允許臟讀,也就是可能讀取到其他會話中未提交事務(wù)修改的數(shù)據(jù)

提交讀(Read Committed):只能讀取到已經(jīng)提交的數(shù)據(jù)。Oracle等多數(shù)數(shù)據(jù)庫默認(rèn)都是該級別 (不重復(fù)讀)

可重復(fù)讀(Repeated Read):可重復(fù)讀。在同一個(gè)事務(wù)內(nèi)的查詢都是事務(wù)開始時(shí)刻一致的,InnoDB默認(rèn)級別。在SQL標(biāo)準(zhǔn)中,該隔離級別消除了不可重復(fù)讀,但是還存在幻象讀

串行讀(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞

SQL標(biāo)準(zhǔn)定義了4種隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。

低級別的隔離級一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。

按照SQL:1992 事務(wù)隔離級別,InnoDB默認(rèn)是可重復(fù)讀的(REPEATABLE READ)。

MySQL/InnoDB 提供SQL標(biāo)準(zhǔn)所描述的所有四個(gè)事務(wù)隔離級別。

4 設(shè)置默認(rèn)隔離級別

4.1 查詢?nèi)趾蜁捠聞?wù)隔離級別:

SELECT @@global.tx_isolation;

SELECT @@session.tx_isolation;

SELECT @@tx_isolation;

4.2 啟動時(shí)指定隔離級別(臨時(shí)生效)

在命令行中啟動mysql服務(wù)時(shí)用--transaction-isolation {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE} 選項(xiàng)指定隔離級別。

4.3 配置文件添加(每次重啟時(shí)生效)

在配置my.cnf文件的[mysqld]節(jié)里添加如下設(shè)置:

transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}

4.4 客戶端命令行

用戶可以用SET TRANSACTION語句改變單個(gè)會話或者所有新進(jìn)連接的隔離級別。它的語法如下:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};

注意:默認(rèn)的行為(不帶session和global)是為下一個(gè)(未開始)事務(wù)設(shè)置隔離級別。如果你使用GLOBAL關(guān)鍵字,語句在全局對從那點(diǎn)開始創(chuàng)建的所有新連接(除了不存在的連接)設(shè)置默認(rèn)事務(wù)級別。你需要SUPER權(quán)限來做這個(gè)。使用SESSION 關(guān)鍵字為將來在當(dāng)前連接上執(zhí)行的事務(wù)設(shè)置默認(rèn)事務(wù)級別。 任何客戶端都能自由改變會話隔離級別(甚至在事務(wù)的中間),或者為下一個(gè)事務(wù)設(shè)置隔離級別。

5 第1級別:Read Uncommitted(讀取未提交內(nèi)容)

(1)所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果

(2)本隔離級別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌墑e好多少

(3)該級別引發(fā)的問題是——臟讀(Dirty Read):讀取到了未提交的數(shù)據(jù)

#首先,修改隔離級別set tx_isolation='READ-UNCOMMITTED';select @@tx_isolation;+------------------+| @@tx_isolation? |+------------------+| READ-UNCOMMITTED |+------------------+#事務(wù)A:啟動一個(gè)事務(wù)start transaction;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)B:也啟動一個(gè)事務(wù)(那么兩個(gè)事務(wù)交叉了)在事務(wù)B中執(zhí)行更新語句,且不提交start transaction;update tx set num=10 where id=1;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? 10 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)A:那么這時(shí)候事務(wù)A能看到這個(gè)更新了的數(shù)據(jù)嗎?select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? 10 |? ? --->可以看到!說明我們讀到了事務(wù)B還沒有提交的數(shù)據(jù)|? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)B:事務(wù)B回滾,仍然未提交rollback;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)A:在事務(wù)A里面看到的也是B沒有提交的數(shù)據(jù)select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 |? ? --->臟讀意味著我在這個(gè)事務(wù)中(A中),事務(wù)B雖然沒有提交,但它任何一條數(shù)據(jù)變化,我都可以看到!|? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+

6 第2級別:Read Committed(讀取提交內(nèi)容)

(1)這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)

(2)它滿足了隔離的簡單定義:一個(gè)事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變

(3)這種隔離級別出現(xiàn)的問題是——不可重復(fù)讀(Nonrepeatable Read):不可重復(fù)讀意味著我們在同一個(gè)事務(wù)中執(zhí)行完全相同的select語句時(shí)可能看到不一樣的結(jié)果。

|——>導(dǎo)致這種情況的原因可能有:(1)有一個(gè)交叉的事務(wù)有新的commit,導(dǎo)致了數(shù)據(jù)的改變;(2)一個(gè)數(shù)據(jù)庫被多個(gè)實(shí)例操作時(shí),同一事務(wù)的其他實(shí)例在該實(shí)例處理其間可能會有新的commit

#首先修改隔離級別set tx_isolation='read-committed';select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+#事務(wù)A:啟動一個(gè)事務(wù)start transaction;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)B:也啟動一個(gè)事務(wù)(那么兩個(gè)事務(wù)交叉了)在這事務(wù)中更新數(shù)據(jù),且未提交start transaction;update tx set num=10 where id=1;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? 10 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)A:這個(gè)時(shí)候我們在事務(wù)A中能看到數(shù)據(jù)的變化嗎?select * from tx; --------------->+------+------+? ? ? ? ? ? ? ? || id? | num? |? ? ? ? ? ? ? ? |+------+------+? ? ? ? ? ? ? ? ||? ? 1 |? ? 1 |--->并不能看到! ||? ? 2 |? ? 2 |? ? ? ? ? ? ? ? ||? ? 3 |? ? 3 |? ? ? ? ? ? ? ? |+------+------+? ? ? ? ? ? ? ? |——>相同的select語句,結(jié)果卻不一樣? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |#事務(wù)B:如果提交了事務(wù)B呢?? ? ? ? ? ? |commit;? ? ? ? ? ? ? ? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |#事務(wù)A:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |select * from tx; --------------->+------+------+| id? | num? |+------+------+|? ? 1 |? 10 |--->因?yàn)槭聞?wù)B已經(jīng)提交了,所以在A中我們看到了數(shù)據(jù)變化|? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+

7 第3級別:Repeatable Read(可重讀)

(1)這是MySQL的默認(rèn)事務(wù)隔離級別?APP開發(fā)找上海捌躍網(wǎng)絡(luò)科技有限公司

(2)它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會看到同樣的數(shù)據(jù)行

(3)此級別可能出現(xiàn)的問題——幻讀(Phantom Read):當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí),會發(fā)現(xiàn)有新的“幻影” 行

(4)InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題

#首先,更改隔離級別set tx_isolation='repeatable-read';select @@tx_isolation;+-----------------+| @@tx_isolation? |+-----------------+| REPEATABLE-READ |+-----------------+#事務(wù)A:啟動一個(gè)事務(wù)start transaction;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)B:開啟一個(gè)新事務(wù)(那么這兩個(gè)事務(wù)交叉了)在事務(wù)B中更新數(shù)據(jù),并提交start transaction;update tx set num=10 where id=1;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? 10 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+commit;#事務(wù)A:這時(shí)候即使事務(wù)B已經(jīng)提交了,但A能不能看到數(shù)據(jù)變化?select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? ? 1 | --->還是看不到的!(這個(gè)級別2不一樣,也說明級別3解決了不可重復(fù)讀問題)|? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+#事務(wù)A:只有當(dāng)事務(wù)A也提交了,它才能夠看到數(shù)據(jù)變化commit;select * from tx;+------+------+| id? | num? |+------+------+|? ? 1 |? 10 ||? ? 2 |? ? 2 ||? ? 3 |? ? 3 |+------+------+

8 第4級別:Serializable(可串行化)

(1)這是最高的隔離級別;

(2)它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖;

(3)在這個(gè)級別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競爭。

#首先修改隔離界別set tx_isolation='serializable';select @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| SERIALIZABLE? |+----------------+#事務(wù)A:開啟一個(gè)新事務(wù)start transaction;#事務(wù)B:在A沒有commit之前,這個(gè)交叉事務(wù)是不能更改數(shù)據(jù)的start transaction;insert tx values('4','4');ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionupdate tx set num=10 where id=1;ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

轉(zhuǎn)自:http://blog.51cto.com/moerjinrong/2314867

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,016評論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,006評論 2 374

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

  • 一、事務(wù) 1、事務(wù)四要素:ACID 對于事務(wù),我之前的理解是很粗糙的,不就是為了保證操作的原子性么?一般訂單系統(tǒng)或...
    張偉科閱讀 1,337評論 0 5
  • 本文實(shí)驗(yàn)的測試環(huán)境:Windows 10+cmd+MySQL5.6.36+InnoDB 一、事務(wù)的基本要素(ACI...
    秋名山車神_f776閱讀 298評論 0 3
  • 一個(gè)人的時(shí)光 坐擁書齋 以王者氣概,傲睨紅塵 穿越上下五千年,橫跨亞馬遜, 在燈下,以不變的姿態(tài) 擷縷縷墨香文韻。...
    淡泊依然閱讀 231評論 0 3
  • W3C JavaScript Array 對象 concat(array) concat方法用于拼接數(shù)組,a.co...
    Jackson_Z閱讀 621評論 0 2
  • 獲得思想,獲得自由 自我構(gòu)建思想。自由型,選擇標(biāo)準(zhǔn)是有沒有趣味。思想全景,思想者,自由人。一旦擁有了思想,也就有了...
    我是孟祥勇閱讀 308評論 0 0