事務(wù)的隔離級別
十載的圍場網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整圍場建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“圍場網(wǎng)站設(shè)計”,“圍場網(wǎng)站推廣”以來,每個客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
數(shù)據(jù)庫事務(wù)的隔離級別有4個,由低到高依次為Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別可以逐個解決臟讀、不可重復(fù)讀、幻讀這幾類問題。
√: 可能出現(xiàn) ×: 不會出現(xiàn)
臟讀不可重復(fù)讀幻讀
Read uncommitted√√√
Read committed×√√
Repeatable read××√
Serializable×××
注意:我們討論隔離級別的場景,主要是在多個事務(wù)并發(fā)的情況下,因此,接下來的講解都圍繞事務(wù)并發(fā)。
Read uncommitted 讀未提交
公司發(fā)工資了,領(lǐng)導(dǎo)把5000元打到singo的賬號上,但是該事務(wù)并未提交,而 singo正好去查看賬戶,發(fā)現(xiàn)工資已經(jīng)到賬,是5000元整,非常高興。可是不幸的是,領(lǐng)導(dǎo)發(fā)現(xiàn)發(fā)給singo的工資金額不對,是2000元,于是迅速 回滾了事務(wù),修改金額后,將事務(wù)提交,最后singo實(shí)際的工資只有2000元,singo空歡喜一場。
出現(xiàn)上述情況,即我們所說的臟讀,兩個并發(fā)的事務(wù),“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”、“事務(wù)B:singo查詢工資賬戶”,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)。
當(dāng)隔離級別設(shè)置為Read uncommitted時,就可能出現(xiàn)臟讀,如何避免臟讀,請看下一個隔離級別。
Read committed 讀提交
singo拿著工資卡去消費(fèi),系統(tǒng)讀取到卡里確實(shí)有2000元,而此時她的老婆也正好 在網(wǎng)上轉(zhuǎn)賬,把singo工資卡的2000元轉(zhuǎn)到另一賬戶,并在singo之前提交了事務(wù),當(dāng)singo扣款時,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有 錢,扣款失敗,singo十分納悶,明明卡里有錢,為何......
出現(xiàn)上述情況,即我們所說的不可重復(fù)讀,兩個并發(fā)的事務(wù),“事務(wù)A:singo消費(fèi)”、“事務(wù)B:singo的老婆網(wǎng)上轉(zhuǎn)賬”,事務(wù)A事先讀取了數(shù)據(jù),事務(wù)B緊接了更新了數(shù)據(jù),并提交了事務(wù),而事務(wù)A再次讀取該數(shù)據(jù)時,數(shù)據(jù)已經(jīng)發(fā)生了改變。
當(dāng)隔離級別設(shè)置為Read committed時,避免了臟讀,但是可能會造成不可重復(fù)讀。
大多數(shù)數(shù)據(jù)庫的默認(rèn)級別就是Read committed,比如Sql Server , Oracle。如何解決不可重復(fù)讀這一問題,請看下一個隔離級別。
Repeatable read 重復(fù)讀
當(dāng)隔離級別設(shè)置為Repeatable read時,可以避免不可重復(fù)讀。當(dāng)singo拿著工資卡去消費(fèi)時,一旦系統(tǒng)開始讀取工資卡信息(即事務(wù)開始),singo的老婆就不可能對該記錄進(jìn)行修改,也就是singo的老婆不能在此時轉(zhuǎn)賬。
雖然Repeatable read避免了不可重復(fù)讀,但還有可能出現(xiàn)幻讀。
singo的老婆工作在銀行部門,她時常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費(fèi) 記錄。有一天,她正在查詢到singo當(dāng)月信用卡的總消費(fèi)金額(select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞后在收銀臺買單,消費(fèi)1000元,即新增了一條1000元的消費(fèi)記錄(insert transaction ... ),并提交了事務(wù),隨后singo的老婆將singo當(dāng)月信用卡消費(fèi)的明細(xì)打印到A4紙上,卻發(fā)現(xiàn)消費(fèi)總額為1080元,singo的老婆很詫異,以為出 現(xiàn)了幻覺,幻讀就這樣產(chǎn)生了。
注:Mysql的默認(rèn)隔離級別就是Repeatable read。
Serializable 序列化
Serializable是最高的事務(wù)隔離級別,同時代價也花費(fèi)最高,性能很低,一般很少使用,在該級別下,事務(wù)順序執(zhí)行,不僅可以避免臟讀、不可重復(fù)讀,還避免了幻像讀。
oracle數(shù)據(jù)庫本身就是讀寫分離的。如果是防止臟讀,那么直接用一個庫就可以了。
如果你是想把大查詢放到從庫,實(shí)時業(yè)務(wù)放主庫,防止查詢影響主庫效率,那最簡單的就是把你的查詢鏈接數(shù)據(jù)庫連到從庫上,甚至可以配一個server,先嘗試連從庫,從庫連不上連主庫。
dbwr 進(jìn)程掃描 db buffer cache, 將其中被修改過的數(shù)據(jù)塊(即臟數(shù)據(jù))寫出至磁盤.
A B 兩用戶,A 在10點(diǎn)更改X表的10到20 但一直未提交,B在10:30 要讀取X表的A更改的那條記錄的值,這時恰好B要讀取的塊在內(nèi)存里面(由于A更改需要把數(shù)據(jù)讀取到內(nèi)存)。這時候有幾種情況,假如此時ORACLE允許B讀取到A更改后但未提交的數(shù)據(jù),這時就發(fā)生了臟讀。另外就是不讓B讀取到A的更改,讀取到A更改以前的數(shù)據(jù),這時就發(fā)生了一致性讀。一致性讀會從現(xiàn)在的臟塊和undo記錄 構(gòu)造一個CR塊 構(gòu)造出來的CR塊與磁盤上的塊是一致的 我的理解是這樣的 當(dāng)然情況不只上面這一種,很多種情況 建議你看看 oracle隔離級別 相關(guān)的文章 應(yīng)該會有用