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