在MySQL中,事務隔離級別RC(read commit)和RR(repeatable read)兩種事務隔離級別基於多版本並發控制MVCC(multi-version concurrency control)來實現。
由於RC隔離級別需要保持語句級別的一致行,事務中每一次讀取都是訪問當前時間點的已提交數據,因此事務中多條查詢語句會創建多個不同的ReadView,開銷較大,復雜度更高,而對於RR隔離級別,僅需要一個版本的ReadView,消耗更少,因此Mysql默認使用RR隔離級別。 RC隔離級別獲得的是語句級讀一致性 RR隔離級別獲得的是事務級讀一致性 對於RC隔離級別,訪問的數據是每次語句執行時間點的數據,而對於RR隔離級別,訪問的數據是事務中第一條語句執行時間點的數據。 If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction. With READ COMMITTED isolation level, each consistent read within a transaction sets and reads its own fresh snapshot. 在RR隔離級別下,執行start transaction命令后,並未開啟事務,而是等到第一條語句執行時開啟事務並建立一致性讀的snapshot,如果希望在start transaction時就建立一致行讀的snapshot,可以使用START TRANSACTION WITH consistent snapshot。
對於RC隔離級別,不需要解決幻讀的問題,"當前讀"操作只對掃描到的數據進行加鎖(行鎖),無須使用GAP鎖。 對於RR隔離級別,需要防止幻讀的問題,"當前讀"操作除對燒苗到的數據進行加鎖外,還需要使用GAP鎖來防止數據插入到新記錄。
mysqldump --single-transaction便是基於RR隔離級別來獲取一致性數據。 雖然RR隔離級別保證了數據一致性,但是mysqldump並不會在開始時便獲取所有表的MDL鎖,假設在mysqldump執行期間執行對表TB1的ALTER或DROP操作: 情況1:執行mysqldump的線程先訪問表TB1,然后另外線程執行ALTER或DROP操作,則執行mysqldump的線程獲取到MDL鎖,阻塞執行ALTER或DROP操作的線程。 情況2:線程先執行ALTER或DROP操作,然后mysqldump線程訪問修改的表TB1,由於執行ALTER或DROP操作的線程已經修改了TB1的結構,導致執行mysqldump的線程無法獲得一致性數據,最終mysqldump失敗。