高性能MYSQL的事物隔離級別
數(shù)據(jù)庫事務的隔離級別有4種,由低到高分別為Read uncommitted 车要、Read committed 允粤、Repeatable read 、Serializable 翼岁。而且类垫,在事務的并發(fā)操作中可能會出現(xiàn)臟讀,不可重復讀琅坡,幻讀悉患。下面通過事例一一闡述它們的概念與聯(lián)系。
Read uncommitted
讀未提交榆俺,顧名思義售躁,就是一個事務可以讀取另一個未提交事務的數(shù)據(jù)。
事例:老板要給小明發(fā)工資茴晋,小明的工資是3.6萬/月迂求。但是發(fā)工資時老板不小心按錯了數(shù)字,按成3.9萬/月晃跺,該錢已經(jīng)打到小明的戶口揩局,但是事務還沒有提交,就在這時掀虎,小明去查看自己這個月的工資凌盯,發(fā)現(xiàn)比往常多了3千元付枫,以為漲工資了非常高興。但是老板及時發(fā)現(xiàn)了不對驰怎,馬上回滾差點就提交了的事務阐滩,將數(shù)字改成3.6萬再提交。
分析:實際小明這個月的工資還是3.6萬县忌,但是小明看到的是3.9萬掂榔。他看到的是老板還沒提交事務時的數(shù)據(jù)。這就是臟讀症杏。
那怎么解決臟讀呢装获?Read committed!讀提交厉颤,能解決臟讀問題穴豫。
Read committed
讀提交,顧名思義逼友,就是一個事務要等另一個事務提交后才能讀取數(shù)據(jù)精肃。
事例:小明拿著信用卡去享受生活(卡里當然是只有3.6萬),當他埋單時(小明事務開啟)帜乞,收費系統(tǒng)事先檢測到他的卡里有3.6萬司抱,就在這個時候!黎烈!小明的妻子要把錢全部轉(zhuǎn)出充當家用习柠,并提交。當收費系統(tǒng)準備扣款時怨喘,再檢測卡里的金額,發(fā)現(xiàn)已經(jīng)沒錢了(第二次檢測金額當然要等待妻子轉(zhuǎn)出金額事務提交完)振定。小明就會很郁悶必怜,明明卡里是有錢的…
分析:這就是讀提交,若有事務對數(shù)據(jù)進行更新(UPDATE)操作時后频,讀操作事務要等待這個更新操作事務提交后才能讀取數(shù)據(jù)梳庆,可以解決臟讀問題。但在這個事例中卑惜,出現(xiàn)了一個事務范圍內(nèi)兩個相同的查詢卻返回了不同數(shù)據(jù)膏执,這就是不可重復讀。
那怎么解決可能的不可重復讀問題露久?Repeatable read 更米!
Repeatable read
重復讀,就是在開始讀取數(shù)據(jù)(事務開啟)時毫痕,不再允許修改操作
事例:小明拿著信用卡去享受生活(卡里當然是只有3.6萬)征峦,當他埋單時(事務開啟迟几,不允許其他事務的UPDATE修改操作),收費系統(tǒng)事先檢測到他的卡里有3.6萬栏笆。這個時候他的妻子不能轉(zhuǎn)出金額了类腮。接下來收費系統(tǒng)就可以扣款了。
分析:重復讀可以解決不可重復讀問題蛉加。寫到這里蚜枢,應該明白的一點就是,不可重復讀對應的是修改针饥,即UPDATE操作厂抽。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作打厘,而不是UPDATE操作修肠。
什么時候會出現(xiàn)幻讀?
事例:小明某一天去消費户盯,花了2千元嵌施,然后他的妻子去查看他今天的消費記錄(全表掃描FTS,妻子事務開啟)莽鸭,看到確實是花了2千元吗伤,就在這個時候,小明花了1萬買了一部電腦硫眨,即新增INSERT了一條消費記錄足淆,并提交。當妻子打印小明的消費記錄清單時(妻子事務提交)礁阁,發(fā)現(xiàn)花了1.2萬元巧号,似乎出現(xiàn)了幻覺,這就是幻讀姥闭。
那怎么解決幻讀問題丹鸿?Serializable!
Serializable 序列化
Serializable 是最高的事務隔離級別棚品,在該級別下靠欢,事務串行化順序執(zhí)行,可以避免臟讀铜跑、不可重復讀與幻讀门怪。但是這種事務隔離級別效率低下,比較耗數(shù)據(jù)庫性能锅纺,一般不使用掷空。
值得一提的是:大多數(shù)數(shù)據(jù)庫默認的事務隔離級別是Read committed,比如Sql Server , Oracle。Mysql的默認隔離級別是Repeatable read拣帽。