程序員經(jīng)典面試題,談一談MySQL中的事務(wù)
我們都知道,計算機處理的速度非常地快,但是再快的計算機,也面臨著這樣的問題,同一個時間里面有著非常多的請求都要對統(tǒng)一資源發(fā)生操作。所以,在數(shù)據(jù)庫中,引入事務(wù)來解決這樣的問題。
我們舉個簡單的例子,我在街上買了2排益力多,要支付寶轉(zhuǎn)25元給商家,這個時候會這樣操作,支付寶先檢查我的余額是否還有25元,然后從我的余額中扣取25元,然后商家的支付寶增加25元。假如我的支付寶剛好只有25元,在轉(zhuǎn)給商家的瞬間,我用另外一個手機,在拼多多上面買了一個20元的西瓜,也用支付寶支付,因為有了數(shù)據(jù)庫事務(wù),這兩個操作并不會同時成功。
Mysql的數(shù)據(jù)庫有著4大特性,我們稱之為ACID。即原子性,一致性,隔離性,與持久性。
原子性(atomicity)一個事務(wù)必須被視為一個不可分割的最小工作單元,整個事務(wù)中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務(wù)來說,不可能只執(zhí)行其中的一部分操作,這就是事務(wù)的原子性。在上述例子中,要么我扣了25元,益力多的商家多了25元,要么我不扣錢,商家也不多錢。不會存在扣了我的錢,商家又沒收到錢的情況。那估計每天都是各種投訴跟糾紛。
一致性(consistency)數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉(zhuǎn)換到另一個一致性的狀態(tài)。(在前面的例子中,一致性確保了,這25元要么在我這還沒給商家,要么已經(jīng)到達商家賬戶了,不會存在這25元憑空消失的情況。)
隔離性(isolation)通常來說,一個事務(wù)所做的修改在最終提交以前,對其他事務(wù)是不可見的。(在前面的例子中,當我還在支付給小賣部賣家25元的時候,對于我另外一個在拼多多上付款的事務(wù),是覺得我還有25元的,只有當我整個事務(wù)提交后,另外一個事務(wù)才知道我已經(jīng)扣除了對應(yīng)的數(shù)額。所以,我們在執(zhí)行扣除的時候,同時也要判斷余額是否足夠。)
持久性(durability)一旦事務(wù)提交,則其所做的修改將永久保存到數(shù)據(jù)庫。(此時即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會丟失。)
實時上,如果數(shù)據(jù)庫要嚴格遵循這這個性質(zhì),勢必會造成數(shù)據(jù)庫的性能降低。所以,在InnoDB中,是有著多種不同的事務(wù)級別的。分別是讀未提交,讀已提交,可重復讀,,與串行化四種突通的級別。
讀未提交:別人改數(shù)據(jù)的事務(wù)尚未提交,我在我的事務(wù)中也能讀到。上述例子,假如拼多多的扣款是發(fā)生在我的金額已經(jīng)減少25之后,但是事務(wù)還沒提交,這個時候讀取數(shù)據(jù)庫,就已經(jīng)讀到數(shù)據(jù)是0了。很顯然,如果這個時候,前面的時候回滾了,那么這個讀取到的結(jié)果稱之為臟讀。
讀已提交:別人改數(shù)據(jù)的事務(wù)已經(jīng)提交,我在我的事務(wù)中才能讀到。在上述例子中,如果扣減25的事務(wù)未完成,那么讀到的都是結(jié)果25。假如在后面的事務(wù)中,多次讀取余額,那么就有可能讀到25,可能讀到0,我們稱之為不可重復讀。
可重復讀:別人改數(shù)據(jù)的事務(wù)已經(jīng)提交,我在我的事務(wù)中也不去讀。這種在第一次讀數(shù)據(jù)的時候,實際上就已經(jīng)形成對應(yīng)的視圖,后面只能讀到對應(yīng)的數(shù)據(jù)。
串行:我的事務(wù)尚未提交,別人就別想改數(shù)據(jù)。這個是嚴格串行化,在上述例子中,只有前面的扣除25元完成后,才能開始后面的事務(wù)。

這4種隔離級別,并行性能依次降低,安全性依次提高。好了,今天我們簡單介紹了mysql的事務(wù),不知道對你是否有所啟發(fā),歡迎大家關(guān)注我,共同學習,共同進步。