隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
未提交讀 | 可能 | 可能 | 可能 |
已提交讀 | 不可能 | 可能 | 可能 |
可重複讀 | 不可能 | 不可能 | 可能 |
可串行化 | 不可能 | 不可能 | 不可能 |
按照上面的邏輯來講的話,MySQL的innodb在可重複讀的狀況下是會出現幻讀的現象的,可是實際狀況MySQL在可重複讀的隔離級別下是沒有出現幻讀的狀況。在可重複讀的狀況下MySQL主要是經過MVCC多版本控制來解決可重複讀的狀況下幻讀的狀況。數組
快照讀就是所謂的根據read view去獲取信息和數據,不會加任何的鎖。可是當前讀會獲取獲得全部已經提交數據,按照邏輯上來說的話,在一個事務中第一次當前讀和第二次當前讀的中間有新的事務進行DML操做,這個時候倆次當前讀的結果應該是不一致的,可是實際的狀況倒是在當前讀的這個事務還沒提交以前,全部針對當前讀的數據修改和插入都會被阻塞,主要是由於next-key lock解決了當前讀可能會發生幻讀的狀況。session
next-key lock當使用主鍵索引進行當前讀的時候,會降級爲record lock(行鎖)併發
InnoDB支持MVCC多版本,其中RC(READ COMMITTED)和RR(REPEATABLE READ)隔離級別是利用consistent read view(一致讀視圖)方式支持的。所謂的consistent read view就是在某一時刻給事務系統trx_sys打snapshot(快照),把當時的trx_sys狀態(包括活躍讀寫事務數組)記下來,以後的全部讀操做根據其事務ID(即trx_id)與snapshot中trx_sys的狀態作比較,以此判斷read view對事務的可見性。ide
RR隔離級別(除了GAP鎖以外)和RC隔離級別的差異是建立snapshot時機不一樣。RR隔離級別是在事務開始時刻,確切的說是第一個讀操做建立read view的;RC隔離級別是在語句開始時刻建立read view的。這就意味着RR隔離級別下面一個事務的SELECT操做只會獲取一個read view,可是RC隔離級別下一個事務是能夠獲取多個read view的。性能
建立/關閉read view須要持有trx_sys->mutex,會下降系統性能,5.7版本對此進行優化,在事務提交時session會cache只讀事務的read view。優化
下次建立read view,判斷若是是隻讀事務而且系統的讀寫事務狀態沒有發生變化,即trx_sys沒有向前推動,並且沒有新的讀寫事務產生,就能夠重用上次的read view。線程