MySQL ACID及四种隔离级别的解释
以下內(nèi)容出自《高性能MySQL》第三版,了解事務(wù)的ACID及四種隔離級有助于我們更好的理解事務(wù)運作。
下面舉一個銀行應(yīng)用是解釋事務(wù)必要性的一個經(jīng)典例子。假如一個銀行的數(shù)據(jù)庫有兩張表:支票表(checking)和儲蓄表(savings)。現(xiàn)在要從用戶Jane的支票賬戶轉(zhuǎn)移200美元到她的儲蓄賬戶,那么至少需要三個步驟:
1、檢查支票賬戶的余額高于或者等于200美元。
2、從支票賬戶余額中減去200美元。
3、在儲蓄帳戶余額中增加200美元。
上述三個步驟的操作必須打包在一個事務(wù)中,任何一個步驟失敗,則必須回滾所有的步驟。
?
可以用START TRANSACTION語句開始一個事務(wù),然后要么使用COMMIT提交將修改的數(shù)據(jù)持久保存,要么使用ROLLBACK撤銷所有的修改。事務(wù)SQL的樣本如下:
1. start transaction;
2. select balance from checking where customer_id = 10233276;
3. update checking set balance = balance - 200.00 where customer_id = 10233276;
4. update savings set balance = balance + 200.00 where customer_id = 10233276;
5. commit;
?
ACID表示原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)。一個很好的事務(wù)處理系統(tǒng),必須具備這些標(biāo)準(zhǔn)特性:
?
原子性(atomicity)
一個事務(wù)必須被視為一個不可分割的最小工作單元,整個事務(wù)中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務(wù)來說,不可能只執(zhí)行其中的一部分操作,這就是事務(wù)的原子性
一致性(consistency)
???? 數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉(zhuǎn)換到另一個一致性的狀態(tài)。(在前面的例子中,一致性確保了,即使在執(zhí)行第三、四條語句之間時系統(tǒng)崩潰,支票賬戶中也不會損失200美元,因為事務(wù)最終沒有提交,所以事務(wù)中所做的修改也不會保存到數(shù)據(jù)庫中。)
隔離性(isolation)
???? 通常來說,一個事務(wù)所做的修改在最終提交以前,對其他事務(wù)是不可見的。(在前面的例子中,當(dāng)執(zhí)行完第三條語句、第四條語句還未開始時,此時有另外的一個賬戶匯總程序開始運行,則其看到支票帳戶的余額并沒有被減去200美元。)
持久性(durability)
一旦事務(wù)提交,則其所做的修改不會永久保存到數(shù)據(jù)庫。(此時即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會丟失。持久性是個有占模糊的概念,因為實際上持久性也分很多不同的級別。有些持久性策略能夠提供非常強(qiáng)的安全保障,而有些則未必,而且不可能有能做到100%的持久性保證的策略。)
?
隔離級別:
READ UNCOMMITTED(未提交讀)
在READ UNCOMMITTED級別,事務(wù)中的修改,即使沒有提交,對其他事務(wù)也都是可見的。事務(wù)可以讀取未提交的數(shù)據(jù),這也被稱為臟讀(Dirty Read)。這個級別會導(dǎo)致很多問題,從性能上來說,READ UNCOMMITTED不會比其他的級別好太多,但卻缺乏其他級別的很多好處,除非真的有非常必要的理由,在實際應(yīng)用中一般很少使用。
READ COMMITTED(提交讀)
大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別都是READ COMMTTED(但MySQL不是)。READ COMMITTED滿足前面提到的隔離性的簡單定義:一個事務(wù)開始時,只能"看見"已經(jīng)提交的事務(wù)所做的修改。換句話說,一個事務(wù)從開始直到提交之前,所做的任何修改對其他事務(wù)都是不可見的。這個級別有時候叫做不可重復(fù)讀(nonrepeatble read),因為兩次執(zhí)行同樣的查詢,可能會得到不一樣的結(jié)果
REPEATABLE READ(可重復(fù)讀)
REPEATABLE READ解決了臟讀的問題。該隔離級別保證了在同一個事務(wù)中多次讀取同樣記錄結(jié)果是一致的。但是理論上,可重復(fù)讀隔離級別還是無法解決另外一個幻讀(Phantom Read)的問題。所謂幻讀,指的是當(dāng)某個事務(wù)在讀取某個范圍內(nèi)的記錄時,另一個事務(wù)又在該范圍內(nèi)插入了新的記錄,當(dāng)之前的事務(wù)再次讀取該范圍的記錄時,會產(chǎn)生幻行(Phantom Row)。InnoDB和XtraDB存儲引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)解決了幻讀的問題。
SERIALIZABLE(可串行化)
SERIALIZABLE是最高的隔離級別。它通過強(qiáng)制事務(wù)串行執(zhí)行,避免了前面說的幻讀的問題。簡單來說,SERIALIZABLE會在讀取每一行數(shù)據(jù)都加鎖,所以可能導(dǎo)致大量的超時和鎖爭用問題。實際應(yīng)用中也很少用到這個隔離級別,只有在非常需要確保數(shù)據(jù)的一致性而且可以接受沒有并發(fā)的情況下,才考慮采用該級別。
打鉤說明該隔離級別還存在這種情況,打X代表該隔離級別已經(jīng)解決了這種情況:
?
?
總結(jié)
以上是生活随笔為你收集整理的MySQL ACID及四种隔离级别的解释的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql事务以及加锁机制事务的特征AC
- 下一篇: Quest 公司的Shareplex 与