mysql事務隔離級別詳解

數據庫事務

數據庫事務(transaction)是訪問並可能操作各種數據項的一個數據庫操作序列,這些操作要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。事務由事務開始與事務結束之間執行的全部數據庫操作組成。

性質

  1. 原子性:事務中的所有操作要麼全部提交成功,要麼全部失敗回滾。
  2. 一致性:幾個並行執行的事務,其執行結果必須與按某一順序 串行執行的結果相一致。
  3. 隔離性:一個事務所做的修改在提交之前對其它事務是不可見的。兩個以上的事務不會出現交錯執行的狀態,因爲這樣可能會導致數據不一致。
  4. 持久性:一旦事務提交,其所做的修改便會永久保存在數據庫中。

事務的併發問題

  1. 髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據
  2. 不可重複讀:同一個事務內,多次相同的查詢返回了不同的結果。如,事務A第一次讀取一數據後,事務B對這條數據更新並提交事務[記住是更新操作],此時事務A再次讀取相同數據時,發現與之前讀取的數據不一致。
  3. 幻讀:在一個事務的兩次查詢中數據的記錄數不一致。如,事務A第一次讀取多條數據後,事務B插入或刪除數據[僅僅是插入刪除,不是修改數據],此時事務A再次讀取,發現讀取的記錄數量前後不一致

事務的隔離級別

  1. Read Uncommitted(讀取未提交內容):在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因爲它的性能也不比其他級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)。
  2. Read Committed(讀取提交內容):這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支持所謂的不可重複讀(Nonrepeatable Read),因爲同一事務的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結果。
  3. Repeatable Read(可重讀):這是MySQL的默認事務隔離級別,它確保同一事務的多次讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。
  4. SERIALIZABLE(串行化):只有一個事務提交之後纔會執行另一個事務。在這個級別,可能導致大量的超時現象和鎖競爭。
事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommitted)
不可重複讀(read-committed)
可重複讀(repeatable-read)
串行化(serializable)

mysql事務隔離級別測試

表爲tx表結構:

字段 類型
id int
num int

兩個命令行客戶端分別爲A,B;不斷改變A的隔離級別,在B端修改數據。
##(一)、將A的隔離級別設置爲read uncommitted(未提交讀)
在B未更新數據之前:
客戶端A:
image.png
B更新數據:
客戶端B:
image.png
客戶端A:
image.png
經過上面的實驗可以得出結論,事務B更新了一條記錄,但是沒有提交,此時事務A可以查詢出未提交記錄。造成髒讀現象。未提交讀是最低的隔離級別。
##(二)、將客戶端A的事務隔離級別設置爲read committed(已提交讀)
在B未更新數據之前:
客戶端A:
image.png
B更新數據:
客戶端B:
image.png
客戶端A:
image.png
經過上面的實驗可以得出結論,已提交讀隔離級別解決了髒讀的問題,但是出現了不可重複讀的問題,即事務A在兩次查詢的數據不一致,因爲在兩次查詢之間事務B更新了一條數據。已提交讀只允許讀取已提交的記錄,但不要求可重複讀。

(三)、將A的隔離級別設置爲repeatable read(可重複讀)

在B未更新數據之前:
客戶端A:
image.png
B更新數據:
客戶端B:
image.png
B更新數據:
客戶端B:
image.png
客戶端A:
image.png
B插入數據:
客戶端B:
image.png
客戶端A:
image.png
由以上的實驗可以得出結論,可重複讀隔離級別只允許讀取已提交記錄,而且在一個事務兩次讀取一個記錄期間,其他事務部的更新該記錄。但該事務不要求與其他事務可串行化。例如,當一個事務可以找到由一個已提交事務更新的記錄,但是可能產生幻讀問題(注意是可能,因爲數據庫對隔離級別的實現有所差別)。像以上的實驗,就沒有出現數據幻讀的問題。

(四)、將A的隔離級別設置爲 可串行化 (Serializable)

A端打開事務,B端插入一條記錄
事務A端:
image.png
事務B端:
image.png
因爲此時事務A的隔離級別設置爲serializable,開始事務後,並沒有提交,所以事務B只能等待。
事務A提交事務:
事務A端
image.png
事務B端
image.png
serializable完全鎖定字段,若一個事務來查詢同一份數據就必須等待,直到前一個事務完成並解除鎖定爲止 。是完整的隔離級別,會鎖定對應的數據表格,因而會有效率的問題。

文章參考:
https://www.iteye.com/blog/xm-king-770721
https://www.cnblogs.com/xiaohanlin/p/8644749.html

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