【MySQL數據庫】談談事務的隔離級別有什麼?

分析了一些面試題,發現關於事務的隔離級別問的也很頻繁,於是就特地來學習這一塊的知識,並進行總結整理自己的思路,希望會對有需要的人有一些幫助。

一、所謂事務

事務簡單的來說就是數據庫的一組操作要麼一起成功要麼一起失敗。
事務具有以下四個屬性:原子性、一致性、隔離性、持久性,通常稱爲ACID特性

  • 原子性(atomicity):一個事務是不可分割的工作單位,一個事務中的工作要麼都做,要麼都不做。
  • 一致性(consistency):事務必須是使得數據庫從一個一致性狀態變到另一個一致性狀態,一致性與原子性密不可分。
  • 隔離性(isolation)。一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
  • 持久性(durability)。持久性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。

今天我們主要來探討的是事務的隔離性中的隔離級別。

二、隔離性與隔離級別

爲什麼會有隔離級別的出現呢?原因是當數據庫中多個事務同時執行時,可能出現髒讀(dirty read),不可重複讀(non - repeatable read),幻讀(phantom read)等問題,於是就出現了隔離級別。

  • 髒讀:A事務讀取B事務尚未提交的數據,此時如果B事務發生錯誤並執行回滾操作,那麼A事務讀取到的數據就是髒數據
  • 不可重複讀:一個事務較大,執行時間較長,執行期間前後讀取同一個數據得到的結果不同,就稱爲不可重複讀。
  • 幻讀:事務A在執行讀取操作,需要兩次統計數據的總量,而兩次統計出的數據總量不一致,稱爲幻讀。

注意:不可重複讀是指多次讀取同一個數據的內容不一致,而幻讀是指多次讀取數據總量不一致,對於不重複讀,只需要鎖某一行數據,對於幻讀則需要鎖整個表。

瞭解了出現隔離級別的原因後,再來了解一下隔離級別有哪些:

  • 讀未提交(read uncommitted):一個事務還沒有提交,他做的更改就可以被其它事務看到。
  • 讀提交(read committed):一個事務提交以後,他做的更改纔可以被其它事務看到。
  • 可重複讀(repeatable read):一個事務再執行過程中看到的數據,總和這個事務在啓動時看到的數據一致。
  • 串行化(serializable):對於同一行記錄,讀會加“讀鎖”,寫會加“寫鎖”當發生衝突時,後一個事務必須等前一個事務完執行成後才能繼續執行。

這四種隔離級別,是否存在髒讀、不可重複讀、幻讀的情況:

隔離級別 髒讀 不可重複讀 幻讀
讀未提交
讀提交
可重複讀
串行化

當然隔離級別越高,效率就越低,所以應該找到一個平衡點。
接下來,我們使用一個實例,來進一步瞭解這四個隔離級別。
其中,事務A爲多次讀取數據,事務B爲將V的值由1修改爲2,下面是按照時間順序得執行過程。其中(V1,V2,V3分別代表在不同時間讀取V得值)

事務A 事務B
啓動事務,讀取數據V =1 啓動事務
讀取數據V= 1
將V的值修改爲 2
讀取數據V1
提交事務B
讀取到值V2
提交事務A
讀取到值V3

那麼使用不同得隔離級別,不同時刻得到得值就不相同:

隔離級別 V1值 V2值 V3值
讀未提交 2 2 2
讀提交 1 2 2
可重複讀 1 1 2
串行化 1 1 2

其中讀未提交,表示只要B修改後A立馬就可以讀到修改後得數值;
讀提交是等到B事務提交後,A纔可以讀到B得修改內容;
而可重複讀中,事務A開始讀到得V值是1那麼直到事務A執行結束前,讀到的都是起始時的值1;
對於串行化,由於A事務首先讀到V的值,當B事務準備修改V的值時,就會被鎖定,直到事務A提交後,才能繼續執行B中的操作。

在MySQL中的默認隔離級別是:可重複讀, 而在SQL Sever 和Oracle 中默認隔離級別是:讀提交

這裏爲什麼MySQL不使用讀提交呢?原因是在MySQL5.0版本前,binlog只支持STATEMENT這種複製格式,而這種格式在讀已提交(Read Commited)這個隔離級別下主從複製是有bug的,因此Mysql將可重複讀(Repeatable Read)作爲默認的隔離級別。

三、避免使用長事務

我們瞭解了事務隔離的各種級別後,那麼事務隔離具體是怎樣實現的呢?
在MySQL中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值通過回滾操作都可以得到未修改前的值,不同時刻啓動的事務會有不同的read-view來表示某個操作執行前的狀態。
而長事務意味着系統裏面會存在很老的事務視圖。由於這些事務隨時可能訪問數據庫裏面的任何數據,所以這個事務提交之前,數據庫裏面它可能用到的回滾記錄都必須保留,這就會導致大量佔用存儲空間。

以上就是自己對事務的隔離級別的理解,有任何問題歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章