1.數(shù)據(jù)庫事務(wù)隔離級(jí)別
數(shù)據(jù)庫事務(wù)的隔離級(jí)別有4個(gè)伤靠,由低到高依次為Read uncommitted 、Read committed 啼染、Repeatable read 、Serializable 焕梅,后面三個(gè)級(jí)別可以逐個(gè)解決臟讀 不可重復(fù)讀 迹鹅、幻讀 這幾類問題。
2.總結(jié)
1> 臟讀:當(dāng)事務(wù)隔離級(jí)別為read uncommitted贞言,則可以讀到其他事務(wù)未提交的數(shù)據(jù)斜棚,這是所有隔離級(jí)別中最低的一種。此時(shí)的更改還未提交到數(shù)據(jù)庫该窗,所以稱為臟讀弟蚀。
拓展:對(duì)數(shù)據(jù)庫記錄操作,一般需要打開會(huì)話open session酗失、開啟事務(wù)start transaction义钉、SQL操作、事務(wù)提交commit规肴,而只有事務(wù)提交commit后捶闸,用戶的更改才會(huì)提交到數(shù)據(jù)庫。
2> 不可重復(fù)讀:當(dāng)事務(wù)隔離級(jí)別為read committed拖刃,則當(dāng)前事務(wù)只能讀到其他事務(wù)已提交的數(shù)據(jù)删壮,不能讀到其他事務(wù)未提交的數(shù)據(jù)。
可導(dǎo)致問題:在同一個(gè)事務(wù)中兑牡,讀取到兩次不同的結(jié)果央碟。這種現(xiàn)象叫不可重復(fù)讀。
3> 幻讀:當(dāng)事務(wù)隔離級(jí)別為repeatable read均函,則當(dāng)前事務(wù)可以重復(fù)讀亿虽,就是每次讀取的已有結(jié)果集都相同。但是理論上苞也,可重復(fù)讀隔離級(jí)別還是無法解決幻讀(Phantom Read)問題经柴。所謂幻讀,指的是當(dāng)某個(gè)事務(wù)在讀取某個(gè)范圍內(nèi)的記錄是墩朦,另一個(gè)事務(wù)又在該范圍內(nèi)插入(insert)新的記錄或刪除(delete)已有記錄坯认,當(dāng)之前的事務(wù)再次讀取某個(gè)范圍內(nèi)的記錄時(shí),會(huì)產(chǎn)生幻行(Phantom Row)。
Mysql---InnoDB存儲(chǔ)引擎的幻讀問題:
Mysql數(shù)據(jù)庫的InnoDB和XtraDB存儲(chǔ)引擎通過多版本并發(fā)控制
解決了幻讀問題牛哺。
說明:Mysql數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級(jí)別為 'REPEATABLE-READ'陋气;Oracle數(shù)據(jù)庫默認(rèn)事務(wù)隔離級(jí)別為 'READ COMMITTED'.
親測:薪資表account表。事務(wù)A引润、事務(wù)B統(tǒng)一設(shè)置事務(wù)隔離級(jí)別:repeatable read
1.A:insert B:select
答:當(dāng)事務(wù)A insert一條新紀(jì)錄巩趁,且commit事務(wù)之后,事務(wù)B再次select查詢?nèi)泶靖剑⑽纯吹叫虏迦氲?strong>幻行記錄议慰。(即:直接證明了Mysql---InnoDB存儲(chǔ)引擎,在可重復(fù)讀事務(wù)隔離級(jí)別下解決了可能出現(xiàn)的幻讀問題)
2.A:delete(id=1) B:update(id=1)
答:當(dāng)事務(wù)A刪除了id=1的薪資記錄奴曙,且commti事務(wù)后别凹;事務(wù)B在事務(wù)中更新id=1的薪資記錄。結(jié)果:沒有報(bào)錯(cuò)洽糟,mysql提示信息更新記錄條數(shù)為0炉菲。
mysql> update account set account=1600 where id=1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
3.A:update(id=1) B:update(id=1)
答:初始狀態(tài)id=1的薪資記錄余額account=2000。首先事務(wù)A坤溃、事務(wù)B都進(jìn)入可重復(fù)讀級(jí)別的事務(wù)拍霜,select都查看到余額當(dāng)前為2000。
然后事務(wù)A在2000的基礎(chǔ)上再增加2000元薪介,且commit事務(wù)A祠饺。
緊接著,事務(wù)B在當(dāng)前“2000”元余額基礎(chǔ)上汁政,再加2000元吠裆,事務(wù)B以為薪資應(yīng)該變?yōu)椤?000”+2000=4000±猛辏可是實(shí)際結(jié)果變?yōu)榱?000试疙。Mysql底層自動(dòng)將前面事務(wù)A的更新結(jié)果作為新的余額基礎(chǔ),再加上2000抠蚣。如下圖所示:
4> 序列化級(jí)別:當(dāng)事務(wù)隔離級(jí)別為serializable祝旷,則其他事務(wù)對(duì)數(shù)據(jù)庫的寫操作:insert、update嘶窄、delete將被掛起怀跛;而讀操作:select可正常運(yùn)行不會(huì)被掛起。這個(gè)是隔離級(jí)別中最嚴(yán)格的柄冲,這樣做勢必對(duì)性能造成很大的影響吻谋。
所以在實(shí)際的選用上,我們要根據(jù)當(dāng)前具體的情況選用合適的现横。