此隔離級別中,事務的修改對其他的事務也是可見的,事務可以讀取未提交的資料,也稱為髒讀(dirty read)。很少使用此級別。
大多數資料庫系統預設使用該隔離級別(mysql不是),此隔離級別中事務從開始到提交資料之前,所有的操作對於其他事物都是不見的,也稱作不可重複讀(nonrepeatable),造成2次同樣的查詢可能會得到不同的結果。
可重複讀解決了髒讀的問題,保證了在同乙個事務中多次讀取同樣的記錄的結果是一致的。但是還發解決另外乙個問題--幻讀(phantom read):是指在讀取某個範圍的記錄時,另外乙個事務又在該範圍內插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會產生幻行(phantom row)。innodb和xtradb儲存引擎採用多版本併發控制(mvcc,multiversion concurrency control)解決幻讀的問題。其中mvcc大致可以理解為乙個行級鎖的變種,但是在很多情況下避免了加鎖操作,因此開銷更低。mvcc的實現是通過儲存資料在某個時間點的快照來實現,因此,對於每個事務來說,看到的資料都是一致的。但是對於各個事務的開始時間不同,每個事務對同一張表的,同一時刻看到的資料可能是不一樣的。
下面說下innodb的簡化版mvcc的實現機制:
mvcc通過在每行記錄後面儲存兩個隱藏的列來實現,分別代表,行的建立時間,行的過期時間,這裡時間是指的系統版本號,而不是真正的時間。每開始乙個新的事物,系統版本號會自動遞增。下面列舉在repeatable read隔離級別下,mvcc的具體操作:
select:
innodb會根據以下兩個條件檢查每行記錄:
a.innodb只查詢版本早於當前事物版本的資料行(也就是行的系統版本號小於或等於事 物的系統版本號),這樣可以保證事物讀取的行,要麼是在事物開始前就已經存在,要麼是事務自身插入或修改的。
b.行的刪除版本要麼未定義,要麼大於當前事物的版本號。這樣可以確保事物讀到行在事務開始前未被刪除。
insert:
innodb為新插入的每一行儲存當前系統版本號作為行版本號。
delete:
innodb為刪除的每一行儲存當前系統版本號作為行刪除標識。
update:
innodb為插入的一行新紀錄,儲存當前系統保本號作為行版本號,同時儲存當前系統版本號到原來的行作為行刪除標識。
儲存這兩個額外的版本號,使大多數的讀操作都可以不用加鎖,是的讀資料的操作簡單,效能很好,並且會讀取到符合標準的行,不足時每行記錄都需要額外的儲存空間,需要做更多的行檢查及額外的維護操作。
serializable是最高的隔離級別,它通過強制事務序列執行,避免了前面的幻讀問題,簡單來說,serializable會在讀取的每一行的資料上都加鎖,所以可能導致大量的超時和鎖競爭。只有在非常確保資料一致性而且可以接受沒有併發的情況下,才考慮採用該級別。
mysql隔離級別 MySQL 事務隔離級別
mysql innodb所提供的事務滿足acid的要求,事務是通過事務日誌中的redo log和undo log來實現原子性 undo log 一致性 undo log 永續性 redo log 事務通過鎖機制實現隔離性。1 事務隔離級別與實現read uncommitted 讀未提交 read c...
mysql隔離級別驗證 mysql 隔離級別測試
1 設定隔離級別,包括 全域性 global.tx isolation,會話級別 session.tx isolation mysql workbench的會話 2 建立測試表 注意 unsigned auto increment primary key用法 預設引擎的設定 建立測試表 use te...
Mysql隔離級別
先記錄下幾個概念 髒讀 在當前事務中,讀取到其他事務中還未提交的資料 不可重複讀 在當前事務中,讀取某一行的資料,可能讀出的資料不同 幻讀 在當前事務中,讀取記錄時,另外的事務插入了新的記錄,當前事務可能出現新的行。四種隔離級別 1.未提交讀 可能讀到髒資料 會話a中的隔離級別為未提交讀 表中原來的...