如下內容出自《高性能MySQL》第三版,瞭解事務的ACID及四種隔離級有助於咱們更好的理解事務運做。數據庫
下面舉一個銀行應用是解釋事務必要性的一個經典例子。假如一個銀行的數據庫有兩張表:支票表(checking)和儲蓄表(savings)。如今要從用戶Jane的支票帳戶轉移200美圓到她的儲蓄帳戶,那麼至少須要三個步驟:安全
一、檢查支票帳戶的餘額高於或者等於200美圓。併發
二、從支票帳戶餘額中減去200美圓。性能
三、在儲蓄賬戶餘額中增長200美圓。atom
上述三個步驟的操做必須打包在一個事務中,任何一個步驟失敗,則必須回滾全部的步驟。blog
能夠用START TRANSACTION語句開始一個事務,而後要麼使用COMMIT提交將修改的數據持久保存,要麼使用ROLLBACK撤銷全部的修改。事務SQL的樣本以下:事務
1. start transaction;ci
2. select balance from checking where customer_id = 10233276;it
3. update checking set balance = balance - 200.00 where customer_id = 10233276;io
4. update savings set balance = balance + 200.00 where customer_id = 10233276;
5. commit;
ACID表示原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)。一個很好的事務處理系統,必須具有這些標準特性:
原子性(atomicity)
一個事務必須被視爲一個不可分割的最小工做單元,整個事務中的全部操做要麼所有提交成功,要麼所有失敗回滾,對於一個事務來講,不可能只執行其中的一部分操做,這就是事務的原子性
一致性(consistency)
數據庫老是從一個一致性的狀態轉換到另外一個一致性的狀態。(在前面的例子中,一致性確保了,即便在執行第3、四條語句之間時系統崩潰,支票帳戶中也不會損失200美圓,由於事務最終沒有提交,因此事務中所作的修改也不會保存到數據庫中。)
隔離性(isolation)
一般來講,一個事務所作的修改在最終提交之前,對其餘事務是不可見的。(在前面的例子中,當執行完第三條語句、第四條語句還未開始時,此時有另外的一個帳戶彙總程序開始運行,則其看到支票賬戶的餘額並無被減去200美圓。)
持久性(durability)
一旦事務提交,則其所作的修改不會永久保存到數據庫。(此時即便系統崩潰,修改的數據也不會丟失。持久性是個有佔模糊的概念,由於實際上持久性也分不少不一樣的級別。有些持久性策略可以提供很是強的安全保障,而有些則未必,並且不可能有能作到100%的持久性保證的策略。)
隔離級別:
READ UNCOMMITTED(未提交讀)
在READ UNCOMMITTED級別,事務中的修改,即便沒有提交,對其餘事務也都是可見的。事務能夠讀取未提交的數據,這也被稱爲髒讀(Dirty Read)。這個級別會致使不少問題,從性能上來講,READ UNCOMMITTED不會比其餘的級別好太多,但卻缺少其餘級別的不少好處,除非真的有很是必要的理由,在實際應用中通常不多使用。
READ COMMITTED(提交讀)
大多數數據庫系統的默認隔離級別都是READ COMMTTED(但MySQL不是)。READ COMMITTED知足前面提到的隔離性的簡單定義:一個事務開始時,只能"看見"已經提交的事務所作的修改。換句話說,一個事務從開始直到提交以前,所作的任何修改對其餘事務都是不可見的。這個級別有時候叫作不可重複讀(nonrepeatble read),由於兩次執行一樣的查詢,可能會獲得不同的結果
REPEATABLE READ(可重複讀)
REPEATABLE READ解決了髒讀的問題。該隔離級別保證了在同一個事務中屢次讀取一樣記錄結果是一致的。可是理論上,可重複讀隔離級別仍是沒法解決另一個幻讀(Phantom Read)的問題。所謂幻讀,指的是當某個事務在讀取某個範圍內的記錄時,另外一個事務又在該範圍內插入了新的記錄,當以前的事務再次讀取該範圍的記錄時,會產生幻行(Phantom Row)。InnoDB和XtraDB存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control)解決了幻讀的問題。
SERIALIZABLE(可串行化)
SERIALIZABLE是最高的隔離級別。它經過強制事務串行執行,避免了前面說的幻讀的問題。簡單來講,SERIALIZABLE會在讀取每一行數據都加鎖,因此可能致使大量的超時和鎖爭用問題。實際應用中也不多用到這個隔離級別,只有在很是須要確保數據的一致性並且能夠接受沒有併發的狀況下,才考慮採用該級別。
打鉤說明該隔離級別還存在這種狀況,打X表明該隔離級別已經解決了這種狀況: