? ? ? ?數(shù)據(jù)庫在并發(fā)的情況下,可能會出現(xiàn)臟讀、不可重復(fù)讀、幻讀等問題。為了避免以上問題,數(shù)據(jù)庫事務(wù)增加隔離級別,來保證數(shù)據(jù)的準確性。數(shù)據(jù)庫事務(wù)的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。
1.Read uncommitted(讀未提交)
讀未提交,也就是常說的臟讀,就是一個事務(wù)讀取到其他事務(wù)未提交的數(shù)據(jù),是級別最低的隔離機制。例如,老板給員工發(fā)工資1萬,最后不小心發(fā)了1.2萬,所以員工會看到1.2萬,但是如果老板沒有點擊提交,就可以利用事務(wù)回滾,修改回1萬,然后提交,這是工資就是1萬了。員工看了是1.2萬,但是實際上卻只有1萬,這就是所謂的臟讀。為了解決臟讀問題,可以使用下面的讀提交。
2.Read committed (讀提交)
就是一個事務(wù)要等另一個事務(wù)提交后才能讀取數(shù)據(jù)。例如程序猿老王卡里有10萬,打算買個8萬的禮物,在付款前還查到卡里有10萬,誰知道在付款的時候錢被老王的老婆花光了,導(dǎo)致付款的時候卡里余額已不足。
這就是讀提交,若有事務(wù)對數(shù)據(jù)進行更新(UPDATE)操作時,讀操作事務(wù)要等待這個更新操作事務(wù)提交后才能讀取數(shù)據(jù),可以解決臟讀問題。但在這個事例中,出現(xiàn)了一個事務(wù)范圍內(nèi)兩個相同的查詢卻返回了不同數(shù)據(jù),這就是不可重復(fù)讀。
3.Repeatable read (重復(fù)讀)
當(dāng)老王結(jié)賬的時候,系統(tǒng)開始讀取老王卡里還有多少錢,這個時候老王的老婆就不能敗家了,必須要等老王這個事務(wù)結(jié)束才可以。
重復(fù)讀可以解決不可重復(fù)讀問題,這也是oracle默認的事務(wù)隔離級別。就是一個事務(wù)對同一份數(shù)據(jù)讀取到的相同,不在乎其他事務(wù)對數(shù)據(jù)的修改,寫到這里,應(yīng)該明白的一點就是,不可重復(fù)讀對應(yīng)的是修改,即UPDATE操作。但是可能還會有幻讀問題。因為幻讀問題對應(yīng)的是插入INSERT操作,而不是UPDATE操作,不過會出現(xiàn)幻讀的情況。
就是老王在查看卡里有多少錢時,如果有1萬,想打印出來,這個時候老王買東西花了3000,這個時候打印出來的金額就是7000,出現(xiàn)了幻讀。當(dāng)打印的時候事務(wù)開啟,在事務(wù)提交的時候,中途插入數(shù)據(jù),也就是再消費了,那么最后打印的數(shù)據(jù)和事務(wù)開啟的時候看到的是不一樣的,這就是所謂的幻讀。
4.Serializable(序列化)
Serializable 是最高的事務(wù)隔離級別,在該級別下,事務(wù)串行化順序執(zhí)行,可以避免臟讀、不可重復(fù)讀與幻讀。但是這種事務(wù)隔離級別效率低下,比較耗數(shù)據(jù)庫性能,一般不使用,犧牲了系統(tǒng)的并發(fā)性。
總結(jié):臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀到的就是臟數(shù)據(jù);不可重復(fù)讀:事務(wù)A多次讀取同一數(shù)據(jù)。事務(wù)B在A讀取的過程中修改并提交,導(dǎo)致A讀到的數(shù)據(jù)不一致;幻讀:事務(wù)A讀取數(shù)據(jù)的時候事務(wù)B進行了增加或者刪除,導(dǎo)致A出現(xiàn)了幻覺一樣。不可重復(fù)讀側(cè)重于修改,一般可以使用鎖行解決?;米x側(cè)重于增加或者刪除,需要鎖表。
小結(jié):讀未提交會導(dǎo)致出現(xiàn)臟讀,那么為了解決臟讀,進行讀提交。但是讀提交會導(dǎo)致出現(xiàn)重復(fù)讀,為了解決這個問題,就可以采用重復(fù)讀。但是重復(fù)讀會引出幻讀的問題。不過oracle的默認隔離級別就是重復(fù)讀。如果要解決重復(fù)讀,可以采用序列化,不過會降低效率。