事务的四大特性和隔离级别
1.1 原子性(Atomicity)
第一個原子性,這個是最簡單的。說的是一個事物內(nèi)所有操作共同組成一個原子包,要么全部成功,要么全部失敗。這是最基本的特性,保證了因為一些其他因素導(dǎo)致數(shù)據(jù)庫異常,或者宕機。
1.2 一致性(Consistency)
第二一致性,這個是大家誤解最深的,很多博客都喜歡用銀行轉(zhuǎn)賬的例子來講一直性,所謂的一致性是基于原子性。
原子性只保證了一個事物內(nèi)的所有操作同一性,大家同生死,不會出現(xiàn)你死了,我還活著。但是,原子性并沒有保證大家同一時刻一起生,一起死。計算機指令是有先后順序的,這樣就決定了一個事物的提交,會經(jīng)歷一個時間過程,那么如果事物提交進行到了一半,我讀取了數(shù)據(jù)庫,會不會讀到中間結(jié)果?
為了防止這樣的情況,數(shù)據(jù)庫事物的一致性就規(guī)定了事物提交前后,永遠只可能存在事物提交前的狀態(tài)和事物提交后的狀態(tài),從一個一致性的狀態(tài)到另一個一致性狀態(tài),而不可能出現(xiàn)中間的過程態(tài)。也就是說事物的執(zhí)行結(jié)果是量子化狀態(tài),而不是線性狀態(tài)。
數(shù)據(jù)庫提交事物會有一個過程,如果提交的時候,存在一個時間差,在提交的第一秒,一個刪除過程還沒完成到了第三秒才完成,會不會第一秒訪問的人和第三秒訪問的人得到不同的結(jié)果?出現(xiàn)不一致,狀態(tài)的混沌?這就是一致性得保證的只會有前狀態(tài)和后狀態(tài),絕不會出現(xiàn)中間態(tài)。
1.3 隔離性(Isolation)
事物的隔離性,基于原子性和一致性,因為事物是原子化,量子化的,所以,事物可以有多個原子包的形式并發(fā)執(zhí)行,但是,每個事物互不干擾。
但是,由于多個事物可能操作同一個資源,不同的事物為了保證隔離性,會有很多鎖方案,當(dāng)然這是數(shù)據(jù)庫的實現(xiàn),他們怎么實現(xiàn)的,我們不必深究。
1.4持久性(Durability)
持久性,當(dāng)一個事物提交之后,數(shù)據(jù)庫狀態(tài)永遠的發(fā)生了改變,這個事物只要提交了,哪怕提交后宕機,他也確確實實的提交了,不會出現(xiàn)因為
剛剛宕機了而讓提交不生效,是要事物提交,他就像洗不掉的紋身,永遠的固化了,除非你毀了硬盤。
2.不考慮隔離性可能產(chǎn)生的問題
?
現(xiàn)在重點說明下事務(wù)的隔離性,當(dāng)多個線程(或多個客戶端)都開啟事務(wù)操作數(shù)據(jù)庫中的數(shù)據(jù)時,數(shù)據(jù)庫系統(tǒng)要能進行隔離操作,以保證各個線程獲取數(shù)據(jù)的準(zhǔn)確性。
?
如果不考慮事務(wù)的隔離性,會發(fā)生的幾種問題:
?
2.1 臟讀
?
臟讀是指在一個事務(wù)處理過程中讀取了另一個未提交的事務(wù)中的數(shù)據(jù)。
?
2.2 不可重復(fù)讀
?
不可重復(fù)讀是指對于數(shù)據(jù)庫中的某個數(shù)據(jù),一個事務(wù)內(nèi)多次查詢卻返回了不同的數(shù)據(jù)值,這是由于在事務(wù)執(zhí)行過程中,數(shù)據(jù)被另一個事務(wù)修改并提交了。
?
2.3 幻讀
?
幻讀是事務(wù)非獨立執(zhí)行時發(fā)生的一種現(xiàn)象。例如,事務(wù)T1對一個表中所有的行的某個字段做了從“1”修改為“2”的操作,這時事務(wù)T2又插入了一條新的記錄,而該字段的值為“1”并且提交給數(shù)據(jù)庫。這時,操作事務(wù)T1的用戶如果再查看剛剛修改的數(shù)據(jù),會發(fā)現(xiàn)還有一行沒有修改,其實這行是從事務(wù)T2中添加的,就好像產(chǎn)生幻覺一樣,這就是產(chǎn)生了幻讀。
?
幻讀和不可重復(fù)讀都是讀取了另一條已經(jīng)提交的事務(wù),所不同的是不可重復(fù)讀查詢的都是同一個數(shù)據(jù)項,而幻讀針對的是一批數(shù)據(jù)(比如數(shù)據(jù)的個數(shù))。
?
3.事務(wù)的隔離級別
3.1 read uncommitted : 讀取尚未提交的數(shù)據(jù) :哪個問題都不能解決
3.2 read committed:讀取已經(jīng)提交的數(shù)據(jù) :可以解決臟讀 ---- oracle、sql server、postgresql 默認(rèn)的
3.3 repeatable read:重讀讀取:可以解決臟讀 和 不可重復(fù)讀 ---mysql默認(rèn)的
3.4 serializable:串行化:可以解決 臟讀 不可重復(fù)讀 和 虛讀---相當(dāng)于鎖表
以上四種隔離級別最高的是Serializable,最低的是Read uncommitted級別。當(dāng)然,隔離級別越高,執(zhí)行效率就越低。
?
01:Mysql的默認(rèn)隔離級別是:可重復(fù)讀:Repeatable read;
02:oracle數(shù)據(jù)庫中,只支持seralizable(串行化)級別和Read committed();默認(rèn)的是Read committed級別;
下面就四種隔離級別進行場景設(shè)計:
01: 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實際的工資只有2000元,singo空歡喜一場。
02:Read committed 讀已提交; singo拿著工資卡去消費,系統(tǒng)讀取到卡里確實有2000元,而此時她的老婆也正好在網(wǎng)上轉(zhuǎn)賬,把singo工資卡的2000元轉(zhuǎn)到另一賬戶,并在singo之前提交了事務(wù),當(dāng)singo扣款時,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有錢,扣款失敗,singo十分納悶,明明卡里有錢,為何......
03:Repeatable read 重復(fù)讀 當(dāng)singo拿著工資卡去消費時,一旦系統(tǒng)開始讀取工資卡信息(即事務(wù)開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉(zhuǎn)賬。
04:重復(fù)讀可能出現(xiàn)幻讀: singo的老婆工作在銀行部門,她時常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費記錄。有一天,她正在查詢到singo當(dāng)月信用卡的總消費金額(select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞后在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction ... ),并提交了事務(wù),隨后singo的老婆將singo當(dāng)月信用卡消費的明細打印到A4紙上,卻發(fā)現(xiàn)消費總額為1080元,singo的老婆很詫異,以為出現(xiàn)了幻覺,幻讀就這樣產(chǎn)生了。
Serializabale:最高的事務(wù)隔離級別,代價花費最高,性能很低,很少使用,在此級別下,事務(wù)順序執(zhí)行,避免上述產(chǎn)生的情況。
轉(zhuǎn)載于:https://www.cnblogs.com/codebj/p/11031813.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的事务的四大特性和隔离级别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: a byte of python2微盘_
- 下一篇: c11标准