事務隔離級別有四種,mysql預設使用的是可重複讀,mysql是怎麼實現可重複讀的?為什麼會出現幻讀?是否解決了幻讀的問題?
read uncommitted(未提交讀)
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。讀取未提交的資料,也被稱之為髒讀(dirty read)。該級別用的很少。
read committed(提交讀)
這是大多數資料庫系統的預設隔離級別(但不是mysql預設的)。它滿足了隔離的簡單定義:乙個事務只能看見已經提交事務所做的改變,換句話說就是事務提交之前對其餘事務不可見。這種隔離級別也支援不可重複讀(nonrepeatable read),因為同一事務的其他例項在該例項處理其間可能會有新的commit,所以同一select查詢可能返回不同結果。
repeatable read(可重複讀)
這是mysql的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另乙個棘手的問題:幻讀 (phantom read)。簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另乙個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的「幻影」 行。innodb和falcon儲存引擎通過多版本併發控制(mvcc,multiversion concurrency control)機制解決了該問題(mysql徹底解決了幻讀問題?請往下看)。
serializable(可序列化)
這是最高的隔離級別,它強制事務都是序列執行的,使之不可能相互衝突,從而解決幻讀問題。換言之,它是在每個讀的資料行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。
事務隔離級別
髒讀不可重複讀
幻讀讀未提交(read-uncommitted)是是
是不可重複讀(read-committed)否是
是可重複讀(repeatable-read)否否
是序列化(serializable)否否
否在mysql的眾多儲存引擎中,只有innodb支援事務,所有這裡說的事務隔離級別指的是innodb下的事務隔離級別。
mvcc多版本併發控制(multi-version concurrency control)是mysql中基於樂觀鎖理論實現隔離級別的方式,用於實現讀已提交和可重複讀取隔離級別。
在《高效能mysql》中對mvcc的解釋如下
新建一張表test_zq如下
idtest_id
db_trx_id
db_roll_pt
begin;-- 獲取到全域性事務id
insert into `test_zq` (`id`, `test_id`) values('5','68');
insert into `test_zq` (`id`, `test_id`) values('6','78');
commit;-- 提交事務
複製**
當執行完以上sql語句之後,**中的內容會變成:
idtest_id
db_trx_id
db_roll_pt568
1null678
1null
可以看到,插入的過程中會把全域性事務id記錄到列 db_trx_id 中去
對上述**做刪除邏輯,執行以下sql語句(假設獲取到的事務邏輯id為 3)
begin;--獲得全域性事務id = 3
delete test_zq where id = 6;
commit;
複製**
執行完上述sql之後資料並沒有被真正刪除,而是對刪除版本號做改變,如下所示:
idtest_id
db_trx_id
db_roll_pt568
1null678
13mvcc邏輯流程-修改
修改邏輯和刪除邏輯有點相似,修改資料的時候 會先複製一條當前記錄行資料,同事標記這條資料的資料行版本號為當前是事務版本號,最後把原來的資料行的刪除版本號標記為當前是事務。
執行以下sql語句:
begin;-- 獲取全域性系統事務id 假設為 10
update test_zq set test_id = 22 where id = 5;
commit;
複製**
執行後**實際資料應該是:
idtest_id
db_trx_id
db_roll_pt568
110678
13522
10null
mysql可重複讀和幻讀例項
mysql的預設事務級別是 可重複讀 其中可重複讀是通過mvcc來實現的又叫快照讀,在事務中的讀操作通過對當前的資料庫中記錄乙個版本,以後的讀操作只會讀取記錄的版本,因此相當於對資料庫的資料建立了乙個快照資料,因此叫做快照讀,其不用對資料庫中的資料進行加鎖又叫做樂觀鎖。同時rr事務級別的mysql通...
mysql 可重複讀。
一 可重複讀 我們先看看現象,再分析原理。我的mysql版本是5.5。下面是一張表,只有一條資料,並且我開啟了事物 此時,另乙個事物將record加1,因此我在開啟乙個命令列客戶端,執行下面的命令 成功加1之後,實際上,資料庫中record肯定是2。然後回到之前的客戶端,再查一次 沒毛病,recor...
mysql可重複讀
mysql innodb的預設隔離級別是可重複讀,之前理解有些偏差,查閱一些資料後總結出幾點 首先有兩個概念 一致性檢視 當乙個事務開啟時,innodb會生成乙個檢視,這個檢視是邏輯檢視,通過undo log和row tranzaction id控制實現。在該事務的任何時間點,一致性檢視中的資料都是...