無論你是后端還是DBA,這是一道幾乎必考的題目。
MySQL的事務(wù)具有哪些特性?
原子性:一個事務(wù)中的sql,要么都成功,要么都失敗。
一致性:假如事務(wù)a更新 m和n兩個數(shù)據(jù)源,那么對于其它事務(wù)來說,無論事務(wù)a成功或者失敗,其它事務(wù)讀到的m和n的狀態(tài),要么都是更新前的,要么都是更新后的。
?隔離性:事務(wù)a執(zhí)行過程中,對數(shù)據(jù)的更改,對其它事務(wù)來說是隔離的,至于是否可見,是由事務(wù)的隔離級別控制的。
?持久性:事務(wù)對數(shù)據(jù)的更改是持久落地的。不會憑空消失。
事務(wù)的隔離級別有哪些?
????事務(wù)在不同的隔離級別下,特性是不一樣的,一般最起碼要保證原子性,一致性和持久性。所以MySQL默認(rèn)隔離級別一般是可重復(fù)讀。
1.讀未提交? ? 2.讀已提交? ? 3.可重復(fù)讀? ? 4.串行化
什么是臟讀?
????臟讀簡單來講就是讀到另一個事務(wù)的相對錯誤數(shù)據(jù),只有在讀未提交隔離級別下才會出現(xiàn)這種情況。
假如事務(wù)A在讀未提交隔離級別下讀取到一條事務(wù)B正在修改的數(shù)據(jù),然后由于某種原因,事務(wù)B失敗了,但是事務(wù)A正常執(zhí)行了,這種情況下,事務(wù)A最終讀取到的是錯誤的數(shù)據(jù),這就是臟讀。
什么是不可重復(fù)讀?
????事務(wù)執(zhí)行過程中,前后讀取得數(shù)據(jù)不一致,這就是不可重復(fù)讀。在<讀未提交>隔離級別下,事務(wù)開始讀到一個數(shù)據(jù),然后另一個事務(wù)修改了數(shù)據(jù),無論另一個事務(wù)提交與否,前一個事務(wù)再讀這一條數(shù)據(jù)的時候都會讀到不一樣的值。
????在<讀提交>隔離級別下,同樣會遇到這樣的問題,事務(wù)A開始讀到一個數(shù)據(jù),另一個事務(wù)修改了這個數(shù)據(jù),并且commit,這時候事務(wù)A再讀這條數(shù)據(jù)就會讀到不一樣的值。
什么是幻讀?
幻讀在實(shí)際開發(fā)過程中,即使碰到后只會影響瞬時插入,不會影響數(shù)據(jù)的正確性?;米x的危害遠(yuǎn)遠(yuǎn)小于臟讀和不可重復(fù)讀。
假設(shè)有兩個事務(wù)A和B,當(dāng)事務(wù)A正要插入一條不數(shù)據(jù)時,查詢ID為1的數(shù)據(jù)不存在,恰好這時事務(wù)B已經(jīng)成功插入了同一個唯一ID為1的數(shù)據(jù),這時事務(wù)A執(zhí)行插入就會因?yàn)橹麈I沖突報錯,但是在事務(wù)A中執(zhí)行查詢ID為1的數(shù)據(jù)缺不存在,這就是幻讀。幻讀只有在<串行化>隔離級別下才不會出現(xiàn),其他隔離級別都會出現(xiàn)。但是如果為了避免幻讀,而將隔離級別設(shè)置為串行化,那么數(shù)據(jù)庫的并發(fā)性能將會驟降,一般不會這么做。
總結(jié):
事務(wù)的隔離級別越高,事務(wù)的特性越能得到保證,但是數(shù)據(jù)庫的并發(fā)性能會越低。相反同理。
????MySQL 默認(rèn)的隔離級別是可重復(fù)讀,這種隔離級別下,不會出現(xiàn)臟讀和不可重復(fù)讀的狀況,只會出現(xiàn)幻讀。所以在保證事務(wù)原子和隔離特性的情況下,又想提高數(shù)據(jù)庫性能和并發(fā)能力,一般設(shè)置事務(wù)的隔離級別為可重復(fù)讀。