Mysql數(shù)據(jù)庫有四種隔離級別,read-uncommitted
, read-committed
,repeatable-read
和serializable
解決事務(wù)并發(fā)的臟讀
, 不可重復(fù)讀
以及幻讀
的問題。
臟讀: 在一個事務(wù)中讀取到其他事務(wù)未提交的數(shù)據(jù)
不可重復(fù)讀: 在一個事務(wù)中,兩次讀取數(shù)據(jù)不一致(更新和刪除)
幻讀: 在事務(wù)兩次讀取數(shù)據(jù)的過程中,其他的事務(wù)插入了新的數(shù)據(jù)稽揭,導(dǎo)致兩次讀取的數(shù)據(jù)數(shù)量不一致(增加)
幻讀和不可重復(fù)讀最大的區(qū)別在于解決問題使用的鎖機(jī)制不同,不可重復(fù)讀使用的是行鎖, 幻讀需要使用區(qū)間鎖和NextKey-Lock
事務(wù)隔離級別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
---|---|---|---|
讀未提交(read-uncommitted) | 會 | 會 | 會 |
讀已提交(read-committed) | 不會 | 會 | 會 |
可重復(fù)讀(repeatable-read) | 不會 | 不會 | 會 |
串行化(Serializable) | 不會 | 不會 | 不會 |
讀未提交: 可以讀取其他事務(wù)未提交的數(shù)據(jù)肥卡,當(dāng)其他事務(wù)失敗溪掀,數(shù)據(jù)回滾,就會導(dǎo)致臟讀
讀已提交: 讀取最新的鏡像數(shù)據(jù)步鉴, 事務(wù)A在讀取數(shù)據(jù)之后(未加鎖)膨桥,事務(wù)B對相關(guān)數(shù)據(jù)更新或者刪除并且順利提交之后,事務(wù)A會讀取最新的數(shù)據(jù)唠叛,導(dǎo)致兩次數(shù)據(jù)讀取不一致,引起不可重復(fù)讀問題
可重復(fù)讀: 事務(wù)A讀取當(dāng)前的事務(wù)A當(dāng)前的鏡像沮稚,事務(wù)B對數(shù)據(jù)更新艺沼、刪除、插入之后蕴掏,事務(wù)A依然讀取事務(wù)A當(dāng)前鏡像障般,所以可以避免不可重復(fù)讀問題。(問題: 為什么還存在幻讀問題盛杰?挽荡?)
串行化: 事務(wù)A在結(jié)束之前,事務(wù)B不會開始執(zhí)行即供,所以不會導(dǎo)致任何并發(fā)問題定拟。
MVCC(多版本并發(fā)控制)
原理: 在數(shù)據(jù)行添加隱藏的兩列創(chuàng)建版本號和刪除版本號,每一個一次修改都會生成一個自增的版本號逗嫡。
所以在查詢時需要查詢符合版本條件的數(shù)據(jù)create_version <= current_version < delete_version