不準確,待更新
(因為MySQL通過使用next-key鎖避免了幻讀->RR級別,同一個事務(wù)的相同查詢,可以得到兩個不同的結(jié)果,文中的例子說明說服力還不夠,可以先關(guān)閉MySQL的Gap鎖)
很清楚的一個說明:
五分鐘搞清楚MySQL事務(wù)隔離級別 @傘U
事務(wù)隔離級別:
未提交讀(Read uncommitted),已提交讀(Read committed),可重復讀(Repeatable read),串行讀(Serializable)。
MySQL支持的事務(wù)默認級別是可重復讀,會出現(xiàn)幻讀(插入+刪除)的現(xiàn)象。
| trans_id | start_time | overtime | status | cmt_rbk_time | memo |
|---|---|---|---|---|---|
| 894809860158263330 | 1503902963 | 30 | 2 | 1503902963 | NULL |
MySQL 引擎選擇InnoDB,一個表中的數(shù)據(jù)如上。
現(xiàn)在開啟兩個客戶端,對表中的這條數(shù)據(jù)進行操作
客戶端A和客戶端B如下的SQL語句:
①start transaction;
②select * from trans_context;
③update trans_context set overtime = 31, cmt_rbk_time = cmt_rbk_time + 1 where cmt_rbk_time=1503902963;
④update trans_context set overtime = 32, cmt_rbk_time = cmt_rbk_time + 1 where cmt_rbk_time=1503902963;
⑤commit;
1.客戶端A輸入①開啟一個事務(wù),這時候讀取數(shù)據(jù)庫里的數(shù)據(jù):

A1
2.接著客戶端B輸入①開啟一個事務(wù),并且讀取數(shù)據(jù)庫里的數(shù)據(jù),和客戶端A讀到的數(shù)據(jù)是一樣的:

B1
3.此時客戶端A執(zhí)行③更新語句,再通過②語句查詢,查詢結(jié)果如下,發(fā)現(xiàn)數(shù)據(jù)確實有了變化:

A2
4.此時客戶端B執(zhí)行②查詢語句,查詢結(jié)果如下,在事務(wù)B中的數(shù)據(jù)沒有變化,讀取不到事務(wù)A中的更新:

B2
5.此時在客戶端B中執(zhí)行更新語句,結(jié)果,并不能對這一行數(shù)據(jù)進行更新:

B3
6.此時客戶端A執(zhí)行commit,提交成功,客戶端B會同樣做出反應,提示:

B4
7.在客戶端B中,再次用②查詢數(shù)據(jù),仍然是沒有更新的語句:

B5
8.客戶端B提交commit后再次查詢數(shù)據(jù)時,可以看到客戶端A更新的數(shù)據(jù)了:

B6
總結(jié):MySQL默認的可重復讀,在一個事務(wù)中,是無法讀到別人未提交或已提交的更新數(shù)據(jù)。
當前會話可以重復讀,每次讀取的結(jié)果集都相同,而不管其他事務(wù)有沒有提交。
幻讀
幻讀的問題 @jackbillow

幻讀