這幾天在開發(fā)過程中遇到一個很棘手的問題,兩個不同應(yīng)用環(huán)境中同一塊代碼產(chǎn)生兩種不同的現(xiàn)象租漂,有兩個事務(wù)理盆,第一個事務(wù)進(jìn)行修改操作并且提交事務(wù)俯抖,第二個事務(wù)進(jìn)行查詢输瓜,但查詢到的是修改前的數(shù)據(jù),剛開始以為是Mybatis一級緩存造成的蚌成,但是通過修改sql排除了緩存這種情況前痘,后面確認(rèn)是數(shù)據(jù)庫的事務(wù)隔離級別導(dǎo)致的,因?yàn)閮蓚€數(shù)據(jù)庫的事務(wù)隔離級別分別是:read committed担忧、repeatable read芹缔,隔離級別是repeatable read的會出現(xiàn)上述情況,下面通過對比例子詳細(xì)介紹下:
Mysql數(shù)據(jù)庫的事務(wù)隔離級別
1瓶盛、read uncommitted(讀未提交)
?可以讀取到未提交的數(shù)據(jù)最欠,如果事務(wù)A進(jìn)行修改操作并沒有進(jìn)行提交,但是事務(wù)B就已經(jīng)會讀取到修改后的新數(shù)據(jù)惩猫,這時如果事務(wù)A因?yàn)槟撤N原因回滾芝硬,但是事務(wù)B不會回滾,讀取到的還是修改后的數(shù)據(jù)轧房,因此這種事務(wù)級別會產(chǎn)生大量的臟數(shù)據(jù)? ? ? ? ? ??
2拌阴、read committed(讀已提交)
mysql默認(rèn)的事務(wù)隔離級別,這種事務(wù)級別不會讀取到臟數(shù)據(jù)奶镶,相對于read uncommitted級別迟赃,它在A事務(wù)修改操做未提交之前,事務(wù)B讀取到的是修改前的數(shù)據(jù)厂镇,只有當(dāng)A事務(wù)提交之后纤壁,事務(wù)B讀取的才是修改后的數(shù)據(jù)
3、repeatable read (可重復(fù)讀)
這種事務(wù)隔離級別相對于read committed事務(wù)隔離級別會產(chǎn)生這種現(xiàn)象捺信,如果事務(wù)B之前執(zhí)行過查詢語句酌媒,當(dāng)A事務(wù)修改操作提交之后,事務(wù)B查詢讀取到的仍是修改前的數(shù)據(jù),這一現(xiàn)象說明秒咨,如果事務(wù)B之前執(zhí)行過相同的sql語句喇辽,下次執(zhí)行同樣的sql,不管事務(wù)A做了什么操作雨席,事務(wù)B會重復(fù)讀取原有的數(shù)據(jù)結(jié)果茵臭;如果開啟的事務(wù)B首先不做任何查詢操作,當(dāng)A事務(wù)的修改操作提交之后舅世,這時事務(wù)B才會查詢到修改后的數(shù)據(jù)
4、serializable(串行化)
這種事務(wù)隔離級別是最高的級別奇徒,只有當(dāng)事務(wù)A的寫操作執(zhí)行完之后雏亚,事務(wù)B才能進(jìn)行寫操作,但是讀操作是可以正常進(jìn)行的摩钙,這就相當(dāng)于給這條操作的數(shù)據(jù)加了鎖
事務(wù)隔離級別的基本操作
1罢低、查看當(dāng)前會話的事務(wù)隔離級別
? ? ?select @@tx_isolation
2、查看系統(tǒng)的事務(wù)隔離級別
? ? ?select @@global.tx_isolation
3胖笛、設(shè)置當(dāng)前會話的事務(wù)隔離級別
? ? ?set session transaction isolation level 事務(wù)隔級別
4网持、設(shè)置系統(tǒng)的事務(wù)隔離級別
? ? ?set global transaction isolation level 事務(wù)隔離級別
本地測試驗(yàn)證
一共有四種事務(wù)隔離級別,這里只針對于開發(fā)過程中遇到的由于read committed长踊、repeatable read這種兩種隔離級別導(dǎo)致的問題進(jìn)行本地的驗(yàn)證
1功舀、read committed (讀已提交)
(1)、打開兩個mysql數(shù)據(jù)庫客戶端A身弊、B辟汰,因?yàn)槟J(rèn)是read committed級別,所以不需要設(shè)置阱佛,兩個客戶端開啟事務(wù)A帖汞、B,并執(zhí)行查詢語句
?(2)凑术、在事務(wù)A中進(jìn)行修改操作翩蘸,不要提交,事務(wù)A中查詢結(jié)果已修改淮逊,但是事務(wù)B中查詢到的是修改前的數(shù)據(jù)催首,兩個客戶端查詢結(jié)果
(3)、事務(wù)A進(jìn)行提交壮莹,事務(wù)B查詢到的是修改后的數(shù)據(jù)
2翅帜、repeatable read(可重復(fù)讀)
(1)、設(shè)置系統(tǒng)的事務(wù)隔離級別為:repeatable read
(2)命满、開啟事務(wù)A涝滴、B,并且執(zhí)行同樣的查詢語句
(3)、事務(wù)A中進(jìn)行修改操作歼疮,并且提交杂抽,在事務(wù)B中執(zhí)行查詢語句,查詢到是卻還是修改前的數(shù)據(jù)韩脏,因此這種事務(wù)會導(dǎo)致:如果執(zhí)行相同的查詢語句缩麸,則不管事務(wù)A做了什么操作,則會重復(fù)讀取原來讀取數(shù)據(jù)
(4)赡矢、如果在上面步驟二中杭朱,事務(wù)A中進(jìn)行查詢,然后進(jìn)行修改提交吹散,事務(wù)B開啟事務(wù)后先不進(jìn)行查詢弧械,等事務(wù)A的修改操作提交之后,事務(wù)B再進(jìn)行查詢操作空民,則查詢到的是修改后的數(shù)據(jù)
測試結(jié)論
1刃唐、read committed (讀已提交)這種事務(wù)隔離級別,不管事務(wù)A做什么操作界轩,只有當(dāng)事務(wù)A提交之后画饥,事務(wù)B才會讀取到新的數(shù)據(jù),如果事務(wù)A不提交浊猾,則事務(wù)B不會讀取到新數(shù)據(jù)
2抖甘、repeatable read(可重復(fù)讀)這種事務(wù)隔離級別,如果事務(wù)B在事務(wù)A提交之前做了查詢操作葫慎,然后不管事務(wù)A做了什么操作并且提交后单山,事務(wù)B如果執(zhí)行同樣的查詢語句,則不會讀取到修改后的新數(shù)據(jù)幅疼,會一直重復(fù)讀取剛開始事務(wù)B讀取的數(shù)據(jù)米奸;如果事務(wù)B在事務(wù)A提交之前不做任何查詢操作,則不管事務(wù)A做了什么操作并且提交后爽篷,事務(wù)B查詢到的才是修改后的新數(shù)據(jù)