什么是事务的一致性?一致性和原子性的区别是什么?
(PS:黃色字體為二次修改的內(nèi)容)
關于事務的一致性,《數(shù)據(jù)庫系統(tǒng)概念》中是這樣描述的
第二段說的三個特性是指原子性、隔離性、持久性。
就算這樣,相信大家也是懵懵的,我也是,所以才會寫下這篇博客。
看到別的博客說,一致性是事務的最終目的,原子性、隔離性、持久性都是為了實現(xiàn)一致性。
在這里,我打算驗證一番。
怎么驗證呢?
假設,這個事務系統(tǒng)如果是由我們來設計的話。
首先,場景是這樣的,小范轉100塊錢給小黃,那么這個事務系統(tǒng)必須要保證小范扣了100塊錢,而且小黃也必須要加了100塊錢。
這個我們要怎么保證呢?
有了,我們可以先用一本本子記下來,小范扣100塊錢,小黃加100塊錢,然后,我們再根據(jù)本子上寫的,順序執(zhí)行,這樣的話,小范或者小黃就沒法耍賴了。
OK,那么我們現(xiàn)在就開干,把這個事務系統(tǒng)開發(fā)出來,下面是偽代碼:
//事務系統(tǒng) abstract class transaction{void transaction(){/* todo:將所有操作寫進日志* args: 事務名稱, 事務操作, 事務寫入狀態(tài)(0 未寫完 1已寫完)*/setLog("小范轉100塊錢給小黃", "小范-100", 0);setLog("小范轉100塊錢給小黃", "小黃+100", 1);//獲取日志Log logs = getLog("小范轉100塊錢給小黃");//解析日志,獲取操作事件Event events = parseLog(logs);//執(zhí)行操作并回寫日志狀態(tài)標記該事務已完成doEvent(events, logs);}}OK,系統(tǒng)開發(fā)出來了,我們把它應用上去跑起來試下。
但是,可能是因為計算機內(nèi)存不夠,系統(tǒng)跑到一半,閃退了。。。
也就是doEvent的時候,小范扣了100塊錢,這個時候閃退了。。。
上數(shù)據(jù)庫一看,完了,小范已經(jīng)扣了100,但是小黃并沒有增加100,事務也沒有執(zhí)行下去。
所以我們這個事務系統(tǒng)是有問題的,我們的事務系統(tǒng),應該要保證小范扣100,而且小黃也要加100,我們姑且稱這種狀態(tài)為一致性,因為我們要保證這兩個操作對數(shù)據(jù)而言是一致的嘛。
從目前來看,我們這個事務系統(tǒng),沒有完全實現(xiàn)一致性,那如果發(fā)生了這種狀況,系統(tǒng)閃退停機等等異常情況,我們該怎么處理,才能保證一致性呢?
有了,我們可以在日志中多加一個狀態(tài),用來標記該操作有沒有執(zhí)行,然后用一個定時器,每隔幾秒找出日志中沒有完成的事務,把它執(zhí)行完,這樣一來,就能保證小范扣了100,小黃加了100了,哪怕中途停機了,也能用定時器把事務執(zhí)行完。
就這樣測試了十來次,結果跟操作都一致,確實能保證一致性了,就正式給用上生產(chǎn)環(huán)境了。
可是才不到一天,就出問題了,怎么呢?有個業(yè)務,小張向老李轉賬300元,可是小張的賬戶上只有298,該死的初級程序員又沒有對小張的金額作校驗,直接就給執(zhí)行了。
這下小張的賬戶余額變成了-2,老李的賬戶變成了300。鬧了個大笑話。
這雖然主要責任不在我們開發(fā)的事務系統(tǒng),但是,我們也要做處理,也就是在小張的余額做加減的時候,減成了負數(shù),這個時候程序應該需要拋出異常的,不能讓程序再執(zhí)行下去了,所以,這就需要我們的事務系統(tǒng),可以在執(zhí)行到一半的時候,回滾到初始狀態(tài)。
也就是說,如果同一個事務中,有操作ABC三個順序操作,操作A成功了,操作B失敗了,那這操作C還要執(zhí)行嗎?當然不能,這種情況,B失敗了,我們就只能把A給回滾到操作之前。
這樣一來,我們這個事務系統(tǒng)就是,要么事務都完成,要么事務都不完成,我們姑且就把這個叫做原子性吧。
增加了原子性的功能后,事務系統(tǒng)又開始跑了。
過了幾天,又出問題了,怎么呢?原來啊,小范有300塊錢,小張向小范轉了500塊錢,事務還沒操作完呢,小劉又給小范轉了300塊錢,這樣一來,問題就來了,小張給小范轉500,本應該事務結束的時候小范有800塊錢,可是小劉又給小范轉了300,還是用小范原有的300去增加的,這樣一來,小劉的事務結束,小范就有600塊錢,小張的事務執(zhí)行完,把800寫回給小范,接著,小劉的事務也執(zhí)行完,把600寫回給小范,導致最終小范賬上只有600塊錢,小張的500被吞了。
這樣,數(shù)據(jù)完全混亂了。問題出在哪呢?在于小張事務執(zhí)行的時候,讀取到小范有300,事務沒完,小劉也讀取到小范有300,這樣就錯亂了,我們應該要讓小張在轉賬的時候,小劉要等小張轉完了,才能轉。這樣,才能解決掉數(shù)據(jù)混亂的問題,我們,姑且把這個叫做隔離性。
隔離性修復完之后,項目又開始運作了,事務系統(tǒng)運行了很長一段時間,也沒有出現(xiàn)問題。
到這里,驗證就結束了,上面寫日志的行為其實就是事務的持久性,也可以看到,上面出現(xiàn)的隔離性、原子性、持久性,也都是為了徹底實現(xiàn)一致性而產(chǎn)生的。
所以,總的來說,一致性是一個比較籠統(tǒng)的概念,是事務的基礎,一致性和原子性的區(qū)別就是,原子性強調(diào)的是操作的完整,要么都成功、要么都不成功,而一致性包含的比較多,數(shù)據(jù)的一致性啊等等。
不過其實,我覺得一致性不應該跟原子性、隔離性、持久性放在一起,因為這三個都是為了實現(xiàn)一致性,如果有大佬知道,麻煩跟我說下原因。
到這,本文就結束了,寫的真的不是很好,以后,要是我對事務一致性、原子性有了新的理解,我會再回來修改的,也歡迎各位大佬留言或者私聊我,給我寫關于一致性的啟發(fā)。
知乎上有個回答也是寫的蠻好的,大家可以看看,https://www.zhihu.com/question/30272728
總結
以上是生活随笔為你收集整理的什么是事务的一致性?一致性和原子性的区别是什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 意大利牙膏重大突破发明!1分钟让牙齿“再
- 下一篇: 二维码及验证码的生成