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