事務(wù)的特性ACID
原子性:事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
一致性:事務(wù)的執(zhí)行結(jié)果必須是將數(shù)據(jù)庫從一個狀態(tài)到另一個狀態(tài)。
隔離性:事務(wù)之間的執(zhí)行互不影響如绸。
持久性:事務(wù)一旦提交嘱朽,其對數(shù)據(jù)庫數(shù)據(jù)的修改就是持久的。
事務(wù)的隔離級別:
讀未提交(read uncommit):一個事務(wù)可以讀取到另一個事務(wù)中為提交的修改后的數(shù)據(jù)怔接。
讀提交(read commit):只有一個事務(wù)被提交了燥翅,其修改的數(shù)據(jù)才對其他事務(wù)可見。
可重復(fù)讀(repeatable read):在同一個事務(wù)中蜕提,讀取統(tǒng)一數(shù)據(jù)必須是一致的森书。
串行化(serializable):對同一行數(shù)據(jù)的所有操作都是串行話的。
mysql為什么選擇可重復(fù)讀作為默認(rèn)的事務(wù)隔離級別谎势?
寫說明原因凛膏,為了保證在語句級別的bin log的數(shù)據(jù)一致性。為什么語句級別的bin log會導(dǎo)致數(shù)據(jù)不一致能脏榆?假如在讀提交的隔離級別下猖毫,假如在事務(wù)A的進行過程中,A先進行了兩次更新操作须喂,此時事務(wù)B進行了一次刪除操作吁断,并且事務(wù)B提交了,事務(wù)A再進行其他操作坞生。因為bin log的記錄規(guī)則是事務(wù)的提交順序仔役,那么在bin log中記錄的是事務(wù)B的操作在事務(wù)A之前進行。先進行刪除操作是己,再進行兩次更新操作又兵,必然是錯誤的,將會導(dǎo)致結(jié)果不一致卒废。但是在RR級別在沛厨,事務(wù)B的刪除操作將會堵塞,直到事務(wù)B提交摔认,因為事務(wù)A在更新操作的時候會上X鎖逆皮。即可以避免RC級別下的問題。
事務(wù)不同隔離級別導(dǎo)致的問題
臟讀:指讀取了未提交事務(wù)的數(shù)據(jù)参袱,讀提交可以解決臟讀电谣。
不可重復(fù)讀:事務(wù)A在進行中的時候,進行了一次讀取操作蓖柔,在之后事務(wù)B對數(shù)據(jù)進行了修改辰企,并且提交了事務(wù)风纠,導(dǎo)致事務(wù)A再次進行相同的讀取操作得到的結(jié)果不一樣了况鸣。
幻讀:事務(wù)A進行了兩次讀取操作,發(fā)現(xiàn)讀取出來的數(shù)據(jù)量不同了竹观,原因是有其他事務(wù)在這期間新增了數(shù)據(jù)镐捧。
如何解決不可重復(fù)讀和幻讀潜索?
myysql中通過MVCC(快照讀)來解決不可重復(fù)讀,通過當(dāng)前讀來解決幻讀懂酱。
- 快照讀:每一行數(shù)據(jù)讀冗余了兩個字段竹习,一個是創(chuàng)建版本,一個是刪除版本列牺。版本號隨著事務(wù)的開啟自增整陌,事務(wù)每次取數(shù)據(jù)的時候都會取創(chuàng)建版本號小于當(dāng)前版本號的,以及刪除版本號不存在或者大于當(dāng)前版本號的瞎领。
原理:將歷史數(shù)據(jù)存一份快照泌辫,所以其他事務(wù)增減數(shù)據(jù)對于當(dāng)前書屋來說是不可見的【拍快照讀通過MVCC來控制震放。 - 當(dāng)前讀:當(dāng)前讀通過鎖來控制,當(dāng)前讀包括兩個鎖一個驼修,一個記錄鎖殿遂,一個間隙鎖。我們通過在select語句后面加上 for update(in share mode)乙各。
總結(jié):通過MVCC(快照讀)我們解決了不可重復(fù)讀的問題墨礁,通過當(dāng)前讀我們解決了幻讀的問題。而在RR級別下我們解決了bin log數(shù)據(jù)一致性問題耳峦。