MySQL事務詳解

一、什么是事務

??數據庫中的事務(Transaction)指的是數據庫中的一種執行數據庫操作的一種機制,事務把一組數據操作作為一個整體一起向系統提交或撤銷操作請求,即這一組操作要么全部成功,要么全部失敗,不存在部分成功部分失敗的情況,所有的額操作共進退,因此事務是一個不可分割的邏輯單元。

二、事務的特性(ACID)

??事務有ACID四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
??原子性:指事務是一個不可分割的最小工作單位,事務中的操作只有都發生和都不發生兩種情況。事務中的所有操作必須作為一個整體提交或回滾。如果事務中的任何操作失敗,則整個事務將失敗。
??一致性:事務必須使數據庫從一個一致狀態變換到另外一個一致狀態。也就是說,在事務開始之前,數據庫中存儲的數據處于一致狀態。在正在進行的事務中,數據可能處于不一致的狀態,如數據可能有部分被修改。然而,當事務成功完成時,數據必須再次回到另一個確定的一致狀態。
??隔離性:一個事務的操作對其他事務不可見,即一個事務內部的操作及使用的數據對并發的其他事務是隔離的,并發執行的各個事務之間不能互相干擾。事務之間必須是相互隔離的,它不以任何方式依賴于或影響其他事務。
??持久性:一個事務一旦提交成功,它對數據庫所作的改變是永久性的,即使系統出現故障也是如此。一旦事務被提交,事務對數據所做的任何變動都會被永久地保留在數據庫中。

三、如何實現事務

??MySQL 提供了多種存儲引擎來支持事務,支持事務的存儲引擎有 InnoDB 和 NDB,MyISAM 存儲引擎是不支持事務。其中,InnoDB 存儲引擎事務主要通過 UNDO 日志和 REDO 日志實現。本文討論的事務默認都是基于InnoDB存儲引擎的。在開啟Auto-commit(默認開啟)的情況下,每條 SQL 語句就是一個事務,即SQL 語句執行后自動提交。為了達到將多個操作作為一個事務的目的,需要使用 BEGINSTART TRANSACTION顯示地開啟一個事務,或者關閉當前會話的自動提交。最后使用COMMIT來顯式地提交事務。如果需要撤銷當前事務已經執行的操作所有操作,并回到事務執行前的狀態,可以是用 ROLLBACK來進行回滾。ROLLBACK表示撤銷當前事務,即在事務運行的過程中發生了某種故障,事務不能繼續執行,系統將事務中對數據庫的所有已完成的操作全部撤銷,回滾到事務開始時的狀態。
??MySQL中事務的實現流程大體如下,從BEGINSTART TRANSACTION開始,然后執行一系列操作,最后要執行COMMIT操作來提交事務,事務才算結束。當然,如果需要進行回滾操作,通過執行ROLLBACK事務也會結束。

The Process of Transaction

四、事務的隔離級別

??在介紹事務隔離級別之前,先展示一下在事務并發執行的過程下,可能會遇到的一些問題和場景:
??臟讀(Dirty Read):事務A讀取并使用了另一個事務B修改后尚未提交的數據D, 由于事務B對該數據的修改并未最終提交到數據庫,當事務B回滾時,事務A讀取到的數據D就是“臟數據”,事務A的這種行為稱之為“臟讀”,“臟讀”會導致事務A后續對數據D的所有操作都會產生無法預期的結果。

Dirty Read

??修改丟失(Lost of Modify):當事務A讀取一個數據D時,另外一個事務B也訪問了該數據D,且在事務A成功提交并修改了這個數據D為D1之后,事務B也成功提交并修改了這個數據D為D2。這樣事務A對數據D的修改結果就丟失了,這種情況就被稱為“修改丟失”。

Lost of Modify

??不可重復讀(Unrepeatable Read):事務A需要多次讀取同一數據D,在這個事務還沒結束時,事務B也訪問了這個數據D,并講這個數據D修改成了D1,此時可能會造成事務A多次讀取的數據,這種情況就被稱為不可重復讀。

Unrepeatable Read

??幻讀(Phantom Read):事務A需要多次讀取多行數據D,假設某個階段讀取了N行數據D,此時事務A還沒結束,接著事務B插入了n行新數據D,這樣事務A在隨后的查詢中,會讀取到N+n行的數據D,就好像發生了幻覺一樣,因此這種現象也稱之為“幻讀”。“幻讀”與“不可重復度”類似,“幻讀”側重于數據行數的變化,而“不可重復讀”側重于對同一條數據的內容修改。

Phantom Read

??事務隔離級別就是用來解決上述可能發生的問題和場景的,MySQL支持全部SQL標準定義的四種隔離級別,分別是:
??讀取未提交(READ-UNCOMMITTED):最低的隔離級別,允許一個事務去讀取另一個事務尚未提交的數據變更,可能造成臟讀、修改丟失、不可重復讀、幻讀。
??讀取已提交(READ-COMMITTED):只允許讀取并發事務已經提交的數據,不允許讀取另一個事務尚未提交的數據變更,可以避免臟讀和修改丟失,但是可能造成不可重復、幻讀。
??可重復讀(REPEATABLE-READ):在事務中,對同一字段多次讀取的結果都是一致的,除非本身事務修改,可以避免臟讀、修改丟失和不可重復讀,但是無法避免幻讀。至于幻讀,MySQL的InnoDB采用了間隙鎖(Next-Key鎖)的方式來解決了幻讀問題。
??串行化(SERIALIZABLE):最高的隔離級別,完全服從ACID的隔離級別,所以的事務依次執行,可以避免臟讀、修改丟失、不可重復讀、幻讀。但是串行化的執行效率最低,完全沒有并發可言。

事務隔離級別與對應能解決的問題

五、事務隔離的實現

??MySQL中不同事務隔離級別的實現都是依靠不同機制的鎖來實現的,其實隔離說白了就是枷鎖,不然咋隔離。下面針對針對MySQL提供的四種事務的隔離機制,簡單介紹一下內部實現原理。
??讀取未提交(READ-UNCOMMITTED):“讀取未提交”是MySQL中安全級別最低的事務隔離級別,基本上就等于沒隔離,事務中任何對數據的修改都會第一時間暴露給其他事務,即使當前事務還沒有提交甚至可能在后續的操作中被回滾,但是他不管,沒一步對數據的改變,都能被其他事務所獲取。因為不加鎖的原因,所以數據安全無法保證,但是因為沒有了加鎖和釋放鎖的所帶來的額外開銷,因此“讀取未提交”的并發性能是最高。
??讀取已提交(READ-COMMITTED):既然“讀取未提交”會導致臟數據,那么如果每個事務只允許讀取其他事務已經提交的數據,那么臟數據的問題就可以迎刃而解。“讀取已提交”的實現原理是這樣的:每個事務在操作某條記錄之前開始獲取鎖,如果當前有其他事務已經獲取了該條記錄的鎖,那么該事務獲取鎖失敗,就等待另外是個事務釋放鎖。當持有該記錄鎖的事務提交完成之后,鎖釋放,此時新的事務才能獲取當前記錄的鎖,并對當前數據進行操作。在這種隔離級別下,由于事務的中間狀態不被其他事務所感知,所以可以很好的解決臟讀和修改丟失的問題。
??可重復讀(REPEATABLE-READ):“可重復度”是MySQL默認的事務隔離級別,“可重復讀”是針對“不可重復讀”而言的,前面我們說到過,“不可重復讀”是指同一事務在不同時刻讀到的某挑記錄的內容可能不一致。而“可重復讀”指的是:事務不會讀到其他事務對已有數據的修改,即使其他事務已提交,也就是說,事務開始時讀到的已有數據是什么,在事務提交前的任意時刻,這些數據的值都是一樣的。但是,對于其他事務新插入的數據是可以讀到的,這也就引發了幻讀問題。
??為了實現可重復讀,MySQL 采用了MVCC(Multi-Version Concurrency Control,多版本并發控制)的方式,MVCC 在 MySQL InnoDB 中的實現主要是為了提高數據庫并發性能,用更好的方式去處理讀寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發讀。
??串行化(SERIALIZABLE):串行化是四種種事務隔離級別中隔離要求最嚴格的,它解決了臟讀、可重復讀、幻讀的問題,但是并發效果是最差的,因為它將多個并發事務的執行變為順序執行。讀的時候加共享鎖,其他事務可以并發讀但是不能寫。寫的時候加排它鎖,其他事務既不能并發讀也不能并發寫。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容

  • 事務詳解 注意:MyISAM 不支持事務,InnoDB支持事務,所以所有關于事務, 隔離級別,排它鎖, 共享鎖, ...
    大富帥閱讀 2,861評論 1 3
  • 事務特性ACID 如果一個數據庫聲稱支持事務的操作,那么該數據庫必須要具備以下四個特性: 1 原子性(Atomic...
    Q南南南Q閱讀 929評論 0 0
  • 數據庫事務 1.1數據庫版本 Mysql8.0.12 1.2事務是由一組SQL語句組成的邏輯處理單元,事務具有以下...
    左潔閱讀 218評論 0 0
  • 1.事務的四大特性(AUID) 1.1原子性(Atomicity) 執行一條命令,或者多條命令,要么全部成功,要么...
    IT奔跑的小特閱讀 185評論 0 1
  • 一:什么是事務 二:事務的特性(ACID) 三:臟讀、丟失修改、不可重復讀、幻讀 不可重復讀的重點是修改:多次讀取...
    675ea0b3a47d閱讀 241評論 0 1