基于Spring中的事務(wù)@Transactional細(xì)節(jié)與易錯(cuò)點(diǎn)、幻讀_第1頁
基于Spring中的事務(wù)@Transactional細(xì)節(jié)與易錯(cuò)點(diǎn)、幻讀_第2頁
基于Spring中的事務(wù)@Transactional細(xì)節(jié)與易錯(cuò)點(diǎn)、幻讀_第3頁
基于Spring中的事務(wù)@Transactional細(xì)節(jié)與易錯(cuò)點(diǎn)、幻讀_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第基于Spring中的事務(wù)@Transactional細(xì)節(jié)與易錯(cuò)點(diǎn)、幻讀若是A/B在同一個(gè)類中,A方法有事務(wù),B方法沒有事務(wù),這個(gè)時(shí)候事務(wù)會生效,原因是異常傳導(dǎo)到了A方法中;

A方法沒事務(wù),B方法有事務(wù),A調(diào)用B方法。若是A/B在同一個(gè)類中,B方法事務(wù)失效。A/B在不同的類,B方法有事務(wù)效果。

原因分析:這是動態(tài)代理導(dǎo)致的,當(dāng)要執(zhí)行B方法的回滾時(shí),此時(shí)A調(diào)用的B方法,不是動態(tài)代理的那個(gè)類,無法進(jìn)行回滾。

A方法循環(huán)調(diào)用B方法,A方法有事務(wù),B方法啟用新事務(wù),B方法處理成功一條提交一條的數(shù)據(jù);B方法遇到異常,有異常的那條回滾,不影響之前處理成功提交的數(shù)據(jù)。

從之前的推斷來看,Propagation.REQUIRES_NEW修飾的內(nèi)部方法獨(dú)立一個(gè)新事務(wù),跟外層沒有關(guān)系,其實(shí)是兩個(gè)事務(wù)了,外層事務(wù)回滾內(nèi)存的也不會回滾;內(nèi)層回滾也不影響外層事務(wù)。

但是實(shí)際結(jié)果還是有點(diǎn)不太一樣,若是A/B在不同類中,可以達(dá)到這個(gè)效果;同一個(gè)類的話,就會回滾失敗。跟上面AB方法調(diào)用的結(jié)果類似。

究其原因,還是由于使用了動態(tài)代理來進(jìn)行事務(wù)AOP的,此時(shí)的B方法一旦觸發(fā)回滾就是事務(wù)回滾異常了。那么要想一個(gè)類中兩個(gè)方法間調(diào)用達(dá)到部分提交的效果,需要使用ApplicationContext上下文對象獲取當(dāng)前類對象,再進(jìn)行調(diào)用;

//使用ApplicationContext上下文對象獲取該對象;

@Autowired

privateApplicationContextapplicationContext;

CurrentClassclassService=applicationContext.getBean(CurrentClass.class);

//再用這個(gè)對象去調(diào)用同類的其他方法

classService.b();

總結(jié):事務(wù)的實(shí)現(xiàn)依賴于動態(tài)代理,因此在同一個(gè)類中使用了類的其他方法時(shí),就需要額外注意了,只有使用動態(tài)代理的對象去調(diào)用方法時(shí),才會有事務(wù)回滾的操作。

事務(wù)傳播屬性propagation

propagation代表事務(wù)的傳播行為,默認(rèn)值為Propagation.REQUIRED,總共的屬性信息如下:

Propagation.REQUIRED:如果當(dāng)前存在事務(wù),則加入該事務(wù),如果當(dāng)前不存在事務(wù),則創(chuàng)建一個(gè)新的事務(wù)。(默認(rèn)傳播行為,一定會有一個(gè)事務(wù))

(也就是說如果A方法和B方法都添加了注解,在默認(rèn)傳播模式下,A方法內(nèi)部調(diào)用B方法,會把兩個(gè)方法的事務(wù)合并為一個(gè)事務(wù))

Propagation.SUPPORTS:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。(以當(dāng)前是否有事務(wù)為標(biāo)準(zhǔn),可以有事務(wù),也可以沒有事務(wù))

Propagation.MANDATORY:如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前不存在事務(wù),則拋出異常。(要求當(dāng)前有事務(wù),就能運(yùn)行;沒有就會異常)

Propagation.REQUIRES_NEW:重新創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。

(當(dāng)類A中的a方法用默認(rèn)Propagation.REQUIRED模式,類B中的b方法加上采用Propagation.REQUIRES_NEW模式,然后在a方法中調(diào)用b方法操作數(shù)據(jù)庫,然而a方法拋出異常后,b方法并沒有進(jìn)行回滾,因?yàn)镻ropagation.REQUIRES_NEW會暫停a方法的事務(wù))

Propagation.NOT_SUPPORTED:以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。(以非事務(wù)的方式運(yùn)行,當(dāng)前有不報(bào)錯(cuò))

Propagation.NEVER:以非事務(wù)的方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。

Propagation.NESTED:如果當(dāng)前存在事務(wù),則嵌套事務(wù)內(nèi)執(zhí)行,如果不存在事務(wù)和Propagation.REQUIRED效果一樣。

(也就是說如果A方法和B方法都添加了注解,在A默認(rèn)傳播模式下,B方法加上采用Propagation.NESTED模式,A方法內(nèi)部調(diào)用B方法,A回滾,B也會回滾;但B回滾,A不會回滾)

數(shù)據(jù)庫隔離級別

事務(wù)的隔離級別依賴于數(shù)據(jù)庫的隔離級別,mysql的默認(rèn)隔離級別是可重復(fù)讀(repeatableread),對應(yīng)的效果是在一個(gè)事務(wù)內(nèi)重復(fù)讀取一個(gè)表中的數(shù)據(jù),一直會是一樣的,并不會讀取到那些個(gè)此事務(wù)范圍內(nèi)其他事務(wù)未提交(臟讀)、已提交(不可重復(fù)讀)的修改記錄。

在對數(shù)據(jù)進(jìn)行測試隔離級別時(shí),需要先對數(shù)據(jù)庫進(jìn)行一系列的設(shè)置,包括關(guān)閉自動提交、查看當(dāng)前的隔離級別,相關(guān)命令如下所示:

//由于變量autocommit分會話系統(tǒng)變量與全局系統(tǒng)變量,Value的值為ON,表示autocommit開啟。

OFF表示autocommit關(guān)閉。

showsessionvariableslike'autocommit';

showglobalvariableslike

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論