前一段時間參加了一個國內知名公司的面試,被問及對數據庫的瞭解,自感還不錯,可誰知在隔離等級這種基本概念的點翻個船,也不是由於徹底不懂,而是原本這裏就比較晦澀,加之具體上次看這裏的東西時候已通過了一年多,中間一直在作索引相關優化的工做,因此關於隔離等級的概念點的記憶很模糊,致使了面試時候的啪啪打臉,索性最後安全線度過,如今想來,確實有點發揮失常。在這裏也勸解你們,有時間跟臭味相同的技術員們聊聊天,面面試,不斷回顧一些理論上的知識,而不要一味紮在業務裏不出來。畢竟,你們都是要成爲一名優秀的程序員啊~。囉嗦的話說到這裏,下面進入主題mysql
都知道 innodb 引擎是支持事務這一特性的,由於要介紹事務隔離等級,因此簡單回顧一下事務的特性 ACID程序員
接下來咱們介紹一下具體是根據什麼因素去區分 4 種隔離等級的面試
1,未提交讀(Read uncommited),會產生贓讀,會讀到另外一個事務未提交的數據sql
start A | start B數據庫
select * from test; -> 1,2,3 | -安全
- | insert into test xx values(4)併發
select * from test; -> 1,2,3,4 | -高併發
這裏看到在事務 B 還未提交的狀況下,事務 A 已經能夠讀到新的數據,違反了事務的隔離性、一致性,這種等級通常在業務場景中不多應用,由於徹底沒有事務可言優化
2,已提交讀(Read commited),會產生不可重複讀,會在同一個事務中讀到另外一個事務提交的數據索引
start A | start B
select * from test; -> 1,2,3 | -
- | insert into test xx values(4)
select * from test; -> 1,2,3 | -
- | commit
select * from test; -> 1,2,3,4 | -
能夠看到 A 事務並沒結束,但因爲 B 事務已經提交,這邊已經能夠讀到插入的數據,雖然違反了事務的一致性,但相對而言,已經達到不少業務場景的須要,因此如今不少數據庫都是採用這個等級
3,可重複讀(Repeatable read),會產生幻讀,會在同一個事務中讀到數據後,進行修改但發現數據已經被修改,這個等級也是 innodb 的默認等級。
start A | start B
select * from test; -> 1,2,3 | -
- | insert into test xx values(4)
select * from test; -> 1,2,3 | -
- | commit
select * from test; -> 1,2,3 | -
insert into test xx values(4) 此處報主鍵重複錯誤 | -
這裏看到事務 A 在整個期間,所看到表中的數據沒有發生任何改動,但再最後插入的時候卻報了主鍵重複的錯誤,緣由是由於事務 B 已經成功插入,這就是幻讀想一想,明明沒有,但卻提示我有。這樣說來的話也會存在不少問題,但在實際應用場景中,只要使用得當,就能夠利用 key-next lock 在第三等級完美實現事務特性,此處先不囉嗦了,你們只有知道這個等級,已經能夠確保 mysql 在高併發下清閒的使用了。
4,串行讀(Serializable),無任何問題,隔離等級這一次已經徹底實現了事務特性,但代價是全部的讀寫須要獲取表級的共享鎖、排它鎖。沒法進行事務之間的併發就註定了這種等級是食之無味的雞肋了(固然一些安全等級極高的業務場景也是有可能用到的)
最後給出一張圖總結以上(不少人開始給出圖,我我的以爲浮躁的人懶得看,不浮躁的人看不懂,因此諸位不浮躁的人,恭喜大家看到這裏了)
隔離級別 髒讀(Dirty Read) 不可重複讀(NonRepeatable Read) 幻讀(Phantom Read)
===========================================================================================
未提交讀(Read uncommitted) 可能 可能 可能
已提交讀(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能