李雷和韩梅梅的一次转账事务–事务系统概述
談到事務(wù),我們要做的第一件事,就是理解,什么叫做事務(wù),以及為什么要有事務(wù)。
事務(wù)這個概念的產(chǎn)生,仍然是為了解決我們在之前提到的打字機(jī)問題:
(
http://blog.sina.com.cn/s/blog_693f08470101l1n1.html)
像我們在上文中提到的,計算機(jī)只是一個圖靈機(jī),所以,如果計算機(jī)要實現(xiàn)我們現(xiàn)實的世界的一些操作模式,只能靠模擬的方式進(jìn)行。上次我們是使用鎖來處理一次寫請求過程里面對應(yīng)的多次計算機(jī)操作的時候怎么看起來像是一次整體的操作。而在這里我們要解決的問題是,一組用戶的多次寫入和讀取操作,怎么能夠被看起來像是一次整體的操作呢?首先,讓我用個例子來看看為什么需要這樣做。 為了后面敘述方便,讓我們先設(shè)定一個實際的環(huán)境場景:梅梅給李雷打了一個電話,說最近想買一本英語書,需要一百元,李雷得知梅梅的請求,二話不說就開始操作他的網(wǎng)銀給梅梅做了轉(zhuǎn)賬付款:假定李雷賬戶是pk=1,韓梅梅的賬戶是pk=2
begintransaction;
{查看李雷是否有一百元}
selectcashfromTwherepk=1;A操作
{確定有足夠的錢,減少李雷的錢}
updateTsetcash=cach-100wherepk=1;B操作
{給韓梅梅增加一百元}
updateTsetcach=cash+100wherepk=2;C操作
commit;好,我想我針對事務(wù)場景的場景應(yīng)該描述清楚了。
首先我們來介紹原子性
從業(yè)務(wù)需求來說,我們必須保證,只要李雷的賬戶減少了100塊,那么這一百塊必須能夠加到韓梅梅的賬戶里。如果中間有任何一個操作失敗,系統(tǒng)不能夠憑空多出一百元(李雷沒有減錢,韓梅梅卻加了錢),也不能憑空少了一百元(李雷減少了一百元,韓梅梅賬戶卻沒增加)。
為了做到這個特性,就必須保證李雷賬戶減錢與韓梅梅賬戶加錢這兩件事,要么同時成功,要么同時不成功。
這就是事務(wù)中的第一個重要的概念:原子性的含義
下面我們來介紹一致性
當(dāng)看到自己的賬戶減少了一百塊以后,李雷問電話那頭的梅梅:“梅梅,我看我這里操作成功了,你那里收到錢了沒?”。如果這時候梅梅跟李雷說:”雷~我沒看見我賬戶的錢有變化啊“。
想一想,這時候李雷會是什么感覺?他的心里一定會”咯噔“一下,錢不會是丟了吧?趕緊給支付寶打電話確認(rèn)怎么回事!
因此我做個簡單小結(jié),這里我們需要能夠保證,當(dāng)李雷看到自己賬戶減少了100元的時候,韓梅梅的賬戶里也必須能夠看到增加了一百元。
這種要么同時出現(xiàn),要么同時消失的保證,就是事務(wù)一致性。在看到這里的時候,相信一定會有人來問,這個一致性和原子性,看起來都是要么成功,要么不成功的感覺,那么這兩個概念有什么差異呢?
恩,下面我就來嘗試解決這個疑惑吧~
區(qū)分這倆概念的關(guān)鍵,其實在一個”看”字,一致性約束的是一個用戶寫入并提交數(shù)據(jù)之后,其他用戶去去讀這條記錄的時候,要么看到的是李雷還沒有給韓梅梅轉(zhuǎn)賬的那個狀態(tài),要么就是李雷已經(jīng)成功轉(zhuǎn)賬給了韓梅梅的狀態(tài),而在這兩個狀態(tài)之間的事務(wù)狀態(tài),比如李雷減少了100元,但韓梅梅還沒加上這一百塊的這個中間狀態(tài)則不能夠被其他人看到。而原子性只需要保證操作要么”最終“全部成功,要么”最終“全部失敗而已。原子性不約束可見性,只保證操作的邏輯性。
這,就是一致性和原子性保證的差別。
最后,我們來介紹持久性
我想,任何用戶都一定不希望下述的這種情況發(fā)生:李雷和韓梅梅都已經(jīng)確認(rèn)這次轉(zhuǎn)賬成功了。然而過了5分鐘,韓梅梅想用這充滿了感情的100元去買他想要的英語書的時候,卻發(fā)現(xiàn)錢不翼而飛了!?于是趕緊給支付寶打電話詢問,支付寶卻回答說:對不起您那賬戶的數(shù)據(jù)庫服務(wù)器重啟了,丟失了一部分的數(shù)據(jù),您賬戶里的那個錢正好在丟失范圍內(nèi),請節(jié)哀。
我想這時候應(yīng)該有(bi….)的動機(jī)了吧:)
于是,這里就需要做一個很基礎(chǔ)的保證:如果一個事務(wù)結(jié)束后,已經(jīng)被其他人看到了,那么就不能夠回退到事務(wù)之前的狀態(tài)了。
這就是事務(wù)的第三個重要的概念:持久性的含義
好了,我們介紹了三個關(guān)鍵的概念,原子性A,一致性C,持久性D。下課~
可能有看過其他數(shù)據(jù)庫書籍的人會問了:”等等,你這不對吧?事務(wù)不是四個特性么?別忽悠我們啊,我們明天面試還得背這些概念呢,要不找不到工作啊~”
好好好,我馬上來介紹隔離性。。。
其實,我將隔離性從上面幾個屬性中剝離出來,是有我自己的考慮的,主要原因是我個人認(rèn)為,隔離性從邏輯概念上不與上面介紹的ACD平級。為什么這么說呢?我的理由是,如果要模擬現(xiàn)實中發(fā)生的各種操作,只需要保證ACD三個屬性,就能夠完美的完成一次事務(wù)操作了,隔離性則明顯是多余的。。
”那么,既然多余,去掉不就好了。。還留著他干啥?不知道這個隔離性是最(biiiii…)復(fù)雜的概念么,上次面試就因為沒說明白這貨所以面試被鄙視了呢!”
唉,這還真去不掉,因為去掉了,數(shù)據(jù)庫的事務(wù)就慢的受不了了。。所以數(shù)據(jù)庫開山的那批大牛也就不顧邏輯的清晰不清晰了,把這個概念加入了事務(wù)的四大要素。
從這件事,我們也就能感受到這個概念對性能的重要性了吧。。甚至可以說,數(shù)據(jù)庫事務(wù)性能是否能夠提升,關(guān)鍵就看你能接受哪個隔離級別了呢!
咋樣?是不是對這個概念肅然起敬了?好,那么我們就來看看隔離性是個什么東西。
首先,明確隔離性要解決的問題域,與上面為了保證一次事務(wù)提交邏輯上的正確性不同的,隔離性主要解決的問題是性能,或者更直接點,就是盡可能的降低受到鎖影響的事務(wù)進(jìn)程的個數(shù)的。
然后,看他解決問題的方法:
在之前我們提到,一致性要保證數(shù)據(jù)被其他人看到的時候必須是一個完整的數(shù)據(jù)狀態(tài),數(shù)據(jù)更新過程中的中間狀態(tài)則不能被看到。
好了,大牛們剛剛說了限定條件,下面立馬給自己來了個響亮的自抽。。
隔離性的最低級別,就是讀未提交
什么叫讀未提交呢?我們來抄維基。。
讀未提交,可能出現(xiàn)臟讀,當(dāng)一個事務(wù)試圖讀取另一個還未提交的事務(wù)正在修改的某一行數(shù)據(jù)時,骯臟讀取(dirtyreads)就會發(fā)生。
簡單來說,就是一個事務(wù),需要同時更新兩張表的數(shù)據(jù),而另一個人去讀這兩張表的數(shù)據(jù)的時候,可能能夠讀到一張表的新值和另外一張表的老值!
這明顯就違反了一致性不是:)
其實,從我上面舉出的例子,你就能感受到,一致性和隔離性應(yīng)該被一起考慮,一致性描述的是理想的事務(wù)過程應(yīng)該怎樣,而理想的事務(wù)因為鎖的范圍太大以至于性能難以接受,所以就使用隔離性的多個隔離級別來破壞一致性應(yīng)該給出的保證,以換取更小的鎖范圍,從而獲取更高的性能。
在這一篇,我不會擴(kuò)展隔離性這個概念,因為如果不聯(lián)系實際的數(shù)據(jù)庫實現(xiàn)而死記硬背各種隔離級別的概念,我覺得太難理解這個概念了。
因此,我將在后面展開討論事務(wù)和分布式事務(wù)的章節(jié)再來關(guān)注隔離性的四個級別的問題。在這里,如果你回顧本篇的時候,如果能回想起原子,一致,持久這三個特性產(chǎn)生的原因,然后又能理解到隔離性主要解決的問題域,以及從最低級別:讀未提交,到最高級別:可序列化,隔離性的本質(zhì)就是一個鎖的范圍逐漸擴(kuò)大,性能逐漸降低,但能提供更強級別的一致性保證的這么一個特征。那么我的目標(biāo)也就達(dá)到了。
隨著隔離性概要介紹的完結(jié),數(shù)據(jù)庫系統(tǒng)概述這一章也就隨著這篇概述的結(jié)束而結(jié)束了,在本章,我寫作的主要目標(biāo)就是,用盡可能具象化的例子來對一個數(shù)據(jù)庫系統(tǒng)做了一個概要性的描述。
下面,我會在后面的章節(jié)開始深入到分布式存儲的一些重要的領(lǐng)域進(jìn)行更深入的探討。
enjoy~
轉(zhuǎn)載于:https://blog.51cto.com/aliapp/1325377
總結(jié)
以上是生活随笔為你收集整理的李雷和韩梅梅的一次转账事务–事务系统概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 中使用Expandabl
- 下一篇: Windows系统查看端口占用