mysql 事務隔離簡介

mysql 事務隔離簡介

1 概念掃盲 髒讀 -> 不可重複讀 -> 幻讀

  • 髒讀

    一事務未提交的中間狀態的更新數據 被其他會話讀取到。 當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有 提交到數據庫中(commit未執行),這時,另外會話也訪問這個數據,因爲這個數據是還沒有提交, 那麼另外一個會話讀到的這個數據是髒數據,依據髒數據所做的操作也可能是不正確的。

  • 不可重複讀

    簡單來說就是在一個事務中讀取的數據可能產生變化, 在同一事務中,多次讀取同一數據返回的結果有所不同。換句話說就是,後續讀取可以讀到另一會話事務已提交的更新數據。 相反,“可重複讀”在同一事務中多次讀取數據時,能夠保證所讀數據一樣,也就是,後續讀取不能讀到另一會話事務已提交的更新數據。

  • 幻讀

    簡單來說就是在一個事務中讀取的數據可能產生變化,會話T1事務中執行一次查詢,然後會話T2新插入一行記錄,這行記錄恰好可以滿足T1所使用的查詢的條件。然後T1又使用相同的查詢再次對錶進行檢索,但是此時卻看到了事務T2剛纔插入的新行。這個新行就稱爲“幻像”,因爲對T1來說這一行就像突然 出現的一樣。


2 不可重複讀 & 幻讀 區別

當然,從總的結果來看,似乎兩者都表現爲兩次讀取的結果不一致.

但如果你從控制的角度來看, 兩者的區別就比較大

對於前者, 只需要鎖住滿足條件的記錄

對於後者, 要鎖住滿足條件及其相近的記錄, 甚至可能需要鎖表

很多人容易搞混不可重複讀和幻讀,確實這兩者有些相似。但不可重複讀重點在於update和delete,而幻讀的重點在於insert。

如果使用鎖機制來實現這兩種隔離級別,在可重複讀中,該sql第一次讀取到數據後,就將這些數據加鎖,其它事務無法修改這些數據,就可以實現可重複 讀了。但這種方法卻無法鎖住insert的數據,所以當事務A先前讀取了數據,或者修改了全部數據,事務B還是可以insert數據提交,這時事務A就會 發現莫名其妙多了一條之前沒有的數據,這就是幻讀,不能通過行鎖來避免。需要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低數據庫的併發能力。

  • 所以說不可重複讀和幻讀最大的區別,就在於如何通過鎖機制來解決他們產生的問題。

3 mysql 4 種隔離級別

  • Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
  • Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生
  • Read committed (在一個事物中, 能讀取已提交事物的內容):可避免髒讀的發生。
  • Read uncommitted (能讀取未提交事物裏面的內容):最低級別,任何情況都無法保證。

4 mysql 默認隔離級別 簡介

4.1 默認隔離級別

REPEATABLE-READ (可重複讀):可避免髒讀、不可重複讀的發生

4.2 查詢方式

select @@tx_isolation;

4.3 框架中的默認隔離級別

如果是再 spirng 中 定義了 @Transactional, 如果沒指定隔離級別, 默認爲數據庫事務的隔離級別

ref:

https://www.cnblogs.com/itcomputer/articles/5133254.html

https://www.cnblogs.com/huanongying/p/7021555.html


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