在實際的業務場景中,併發讀寫引出了和事務控制的需求。優秀的事務處理能力是關係型數據庫(特別是oracle等商用RDBMS)相對於正當風口的NoSQL數據庫的一大亮點。但這也從另外一方面說明了事務控制的複雜性——正由於過於複雜,大部分NoSQL都沒提供事務支持或只提供部分事務支持。html
一個數據庫事務是"一個被視爲單一的工做單元的操做序列"
。一個良好的事務處理系統,必須具有四個標準特性:git
以上四個特性就是常說的ACID。其中,隔離性的四個級別是面試常考點。github
在READ UNCOMMITTED級別,事務中的修改,即便沒有提交,對其餘事務也都是可見的。事務能夠讀取未提交的數據,這也被稱爲髒讀(Dirty Read)。這個級別會致使不少問題,從性能上來講,READ UNCOMMITTED不會比其餘的級別好太多,但卻缺少其餘級別的不少好處,除非真的有很是必要的理由,在實際應用中通常不多使用。面試
大多數數據庫系統的默認隔離級別都是READ COMMTTED(但MySQL不是)。READ COMMITTED知足前面提到的隔離性的簡單定義:一個事務開始時,只能"看見"已經提交的事務所作的修改。換句話說,一個事務從開始直到提交以前,所作的任何修改對其餘事務都是不可見的。這個級別有時候叫作不可重複讀(nonrepeatble read),由於兩次執行一樣的查詢,可能會獲得不同的結果。數據庫
REPEATABLE READ解決了髒讀的問題。該隔離級別保證了在同一個事務中屢次讀取一樣記錄結果是一致的。可是理論上,可重複讀隔離級別仍是沒法解決另一個幻讀(Phantom Read)的問題。所謂幻讀,指的是當某個事務在讀取某個範圍內的記錄時,另外一個事務又在該範圍內插入了新的記錄,當以前的事務再次讀取該範圍的記錄時,會產生幻行(Phantom Row)。InnoDB和XtraDB存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control)解決了幻讀的問題。安全
SERIALIZABLE是最高的隔離級別。它經過強制事務串行執行,避免了前面說的幻讀的問題。簡單來講,SERIALIZABLE會在讀取每一行數據都加鎖,因此可能致使大量的超時和鎖爭用問題。實際應用中也不多用到這個隔離級別,只有在很是須要確保數據的一致性並且能夠接受沒有併發的狀況下,才考慮採用該級別。併發
打鉤說明該隔離級別還存在這種狀況,打X表明該隔離級別已經解決了這種狀況:oracle
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀未提交(Read uncommitted) | Y | Y | Y |
讀已提交(Read committed) | X | Y | Y |
可重複讀(Repeatable read) | X | X | Y |
可串行化(Serializable) | X | X | X |
參考:性能
本文連接:事務的ACID和四個隔離級別
做者:猴子007
出處:https://monkeysayhi.github.io
本文基於 知識共享署名-相同方式共享 4.0 國際許可協議發佈,歡迎轉載,演繹或用於商業目的,可是必須保留本文的署名及連接。code