版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
理解Spring中的事務(wù)管理Spring事務(wù)的基本原理Spring事務(wù)的本質(zhì)其實就是數(shù)據(jù)庫對事務(wù)的?持,沒有數(shù)據(jù)庫的事務(wù)?持,Spring是?法提供事務(wù)功能的。對于純JDBC操作數(shù)據(jù)庫,想要?到事務(wù),可以按照以下步驟進(jìn)?:1.獲取連接Connectioncon=DriverManager.getConnection()2.開啟事務(wù)con.setAutoCommit(true/false);3.執(zhí)?CRUD4.提交事務(wù)/回滾事務(wù)mit()/con.rollback();5.關(guān)閉連接conn.close();使?Spring的事務(wù)管理功能后,我們可以不再寫步驟2和4的代碼,?是由Spirng?動完成。那么Spring是如何在我們書寫的CRUD之前和之后開啟事務(wù)和關(guān)閉事務(wù)的呢?解決這個問題,也就可以從整體上理解Spring的事務(wù)管理實現(xiàn)原理了。下?簡單地介紹下,注解?式為例?。1.配置?件開啟注解驅(qū)動,在相關(guān)的類和?法上通過注解@Transactional標(biāo)識。2.spring在啟動的時候會去解析?成相關(guān)的bean,這時候會查看擁有相關(guān)注解的類和?法,并且為這些類和?法?成代理,并根據(jù)@Transaction的相關(guān)參數(shù)進(jìn)?相關(guān)配置注?,這樣就在代理中為我們把相關(guān)的事務(wù)處理掉了(開啟正常提交事務(wù),異?;貪L事務(wù))。3.真正的數(shù)據(jù)庫層的事務(wù)提交和回滾是通過binlog或者redolog實現(xiàn)的。Spring的事務(wù)機(jī)制所有的數(shù)據(jù)訪問技術(shù)都有事務(wù)處理機(jī)制,這些技術(shù)提供了API?來開啟事務(wù)、提交事務(wù)來完成數(shù)據(jù)操作,或者在發(fā)?錯誤的時候回滾數(shù)據(jù)。?Spring的事務(wù)機(jī)制是?統(tǒng)?的機(jī)制來處理不同數(shù)據(jù)訪問技術(shù)的事務(wù)處理。Spring的事務(wù)機(jī)制提供了?個PlatformTransactionManager接?,不同的數(shù)據(jù)訪問技術(shù)的事務(wù)使?不同的接?實現(xiàn),如表所?。數(shù)據(jù)訪問技術(shù)及實現(xiàn)數(shù)據(jù)訪問技術(shù)JDBC實現(xiàn)DataSourceTransactionManagerJapTransactionManagerHibernateTransactionManagerJdoTransactionManagerJtaTransactionManagerJPAHibernateJDO分布式事務(wù)在程序中定義事務(wù)管理器的代碼如下:@Bean(name="xxxTransactionManager")publicPlatformTransactionManagertransactionManager(){JpaTransactionManagertransactionManager=newJpaTransactionManager();transactionManager.setDataSource(dataSource());returntransactionManager;}聲名式事務(wù)Spring?持聲名式事務(wù),即使?注解來選擇需要使?事務(wù)的?法,它使?@Transactional注解在?法上表明該?法需要事務(wù)?持。@TransactionalpublicvoidupdateName(Longid,Stringname){//數(shù)據(jù)庫操作}在此處需要特別注意的是,此@Transactional注解來?org.springframework.transaction.annotation包,?不是javax.transaction。Spring的聲明式事務(wù)管理是建?在SpringAOP機(jī)制之上的,其本質(zhì)是對?標(biāo)?法前后進(jìn)?攔截,并在?標(biāo)?法開始之前創(chuàng)建或者加??個事務(wù),在執(zhí)?完?標(biāo)?法之后根據(jù)執(zhí)?情況提交或者回滾事務(wù)。即向業(yè)務(wù)組件中的?標(biāo)業(yè)務(wù)?法插?事務(wù)增強處理并?成相應(yīng)的代理對象供應(yīng)?程序(客戶端)使?從?達(dá)到?污染地添加事務(wù)的?的。聲明式事務(wù)最?的優(yōu)點就是不需要通過編程的?式管理事務(wù),這樣就不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼,只需通過注解標(biāo)明的?式(或者在配置?件中作相關(guān)的事務(wù)規(guī)則聲明),便可以將事務(wù)規(guī)則應(yīng)?到業(yè)務(wù)邏輯中。總的來說,聲明式事務(wù)得益于SpringIoC容器和SpringAOP機(jī)制的?持:IoC容器為聲明式事務(wù)管理提供了基礎(chǔ)設(shè)施,使得Bean對于Spring框架??是可管理的;?由于事務(wù)管理本?就是?個典型的橫切邏輯(正是AOP的?武之地),因此SpringAOP機(jī)制是聲明式事務(wù)管理的直接實現(xiàn)者。通過SpringAOP,其實現(xiàn)了在?法調(diào)?前、調(diào)?后插??些業(yè)務(wù)邏輯的?的。我們來看?下下?這個圖:上圖顯?,當(dāng)客戶端Callingcode調(diào)??個普通類PlainObject的foo()?法的時候,是直接作?在POJO類??對象上的,客戶端擁有的是被調(diào)?者的直接的引?。?使?了SpringAOP的動態(tài)代理技術(shù)后,即當(dāng)客戶端嘗試調(diào)?POJO的foo()?法的時候,給他的不是POJO??的引?,?是?個動態(tài)?成的代理類。如上圖所?,這個時候,實際客戶端擁有的是?個代理的引?,那么在調(diào)?foo()?法的時候,會?先調(diào)?Proxy的foo()?法,這個時候Proxy可以整體控制實際的POJO.foo()?法的?參和返回值,?如在調(diào)?前及調(diào)?后打印?志,都是可以輕松做到的。Spring中關(guān)于事務(wù)的配置總是由三個部分組成,即:DataSource、TransactionManager和代理機(jī)制三部分,?論哪種配置?式,?般變化的只是代理機(jī)制這部分。其中,DataSource、TransactionManager這兩部分只是會根據(jù)數(shù)據(jù)訪問?式有所變化,?如使?hibernate進(jìn)?數(shù)據(jù)訪問時,DataSource實際為SessionFactory,TransactionManager的實現(xiàn)為HibernateTransactionManager。如下圖所?:兩種動態(tài)代理實現(xiàn)AOPJDK代理的是接?,私有?法必然不會存在在接??,所以就不會被攔截到;CgLib代理的是類,private的?法照樣不會出現(xiàn)在?類?,也不能被攔截。JDK的動態(tài)代理,具體有如下四步驟:通過實現(xiàn)InvocationHandler接?創(chuàng)建??的調(diào)?處理器;通過為Proxy類指定ClassLoader對象和?組interface來?成動態(tài)代理類,這?是動態(tài)?成了代理類的字節(jié)碼;通過反射機(jī)制獲得動態(tài)代理類的構(gòu)造函數(shù),其唯?參數(shù)類型是調(diào)?處理器接?類型;通過構(gòu)造函數(shù)創(chuàng)建動態(tài)代理類實例,構(gòu)造時調(diào)?處理器對象作為參數(shù)被傳?。CgLib(CodeGenerationLibrary)是?個強?的、?性能、?質(zhì)量的Code?成庫,它可以在運?期擴(kuò)展Java類與實現(xiàn)Java接?。Cglib封裝了ASM,可以在運?期動態(tài)?成新的class(?類)Cglib?于AOP,jdk中的proxy必須基于接?,Cglib卻沒有這個限制JDK代理與Cglib的原理區(qū)別Java動態(tài)代理是利?反射機(jī)制?成?個實現(xiàn)代理接?的匿名類,在調(diào)?具體?法前調(diào)?InvokeHandler來處理。?cglib動態(tài)代理是利?asm開源包,將要代理的對象類的class?件加載進(jìn)來,通過修改其字節(jié)碼?成?類來處理。1.如果?標(biāo)對象實現(xiàn)了接?,默認(rèn)情況下會采?JDK的動態(tài)代理實現(xiàn)AOP2.如果?標(biāo)對象實現(xiàn)了接?,可以強制使?CGLIB實現(xiàn)AOP3.如果?標(biāo)對象沒有實現(xiàn)了接?,必須采?CGLIB庫,Spring會?動在JDK動態(tài)代理和CGLIB之間轉(zhuǎn)換如果是類內(nèi)部?法?不了代理,這個時候可以通過維護(hù)?個??實例的代理。@ServicepublicclassPersonServiceImplimplementsPersonService{@AutowiredPersonRepositorypersonRepository;//注???代理對象,在本類內(nèi)部?法調(diào)?事務(wù)的傳遞性才會?效@AutowiredPersonServiceselfProxyPersonService;/***測試事務(wù)的傳遞性**@paramperson*@return*/@TransactionalpublicPersonsave(Personperson){Personp=personRepository.save(person);try{//新開事務(wù)獨?回滾selfProxyPersonService.delete();}catch(Exceptione){e.printStackTrace();}try{//使?當(dāng)前事務(wù)全部回滾selfProxyPersonService.save2(person);}catch(Exceptione){e.printStackTrace();}personRepository.save(person);returnp;}@Transactionalpublicvoidsave2(Personperson){personRepository.save(person);thrownewRuntimeException();}@Transactional(propagation=Propagation.REQUIRES_NEW)publicvoiddelete(){personRepository.delete(1L);thrownewRuntimeException();}}Spring事務(wù)的傳播屬性所謂spring事務(wù)的傳播屬性,就是定義在存在多個事務(wù)同時存在的時候,spring應(yīng)該如何處理這些事務(wù)的?為。這些屬性在TransactionDefinition中定義,具體常量的解釋見下表:Propagation.NESTED(nested嵌套事務(wù)):如果當(dāng)前存在事務(wù),則嵌套在當(dāng)前事務(wù)中。如果當(dāng)前沒有事務(wù),則新建?個事務(wù)??執(zhí)?(和required?樣)。嵌套的事務(wù)使?保存點作為回滾點,當(dāng)內(nèi)部事務(wù)回滾時不會影響外部事物的提交;但是外部回滾會把內(nèi)部事務(wù)?起回滾回去(這是和新建?個事務(wù)的區(qū)別)。Spring中事務(wù)隔離級別?先要了解?下數(shù)據(jù)庫的事務(wù)隔離級別臟讀:?事務(wù)對數(shù)據(jù)進(jìn)?了增刪改,但未提交,另?事務(wù)可以讀取到未提交的數(shù)據(jù)。如果第?個事務(wù)這時候回滾了,那么第?個事務(wù)就讀到了臟數(shù)據(jù)。不可重復(fù)讀:?個事務(wù)中發(fā)?了兩次讀操作,第?次讀操作和第?次操作之間,另外?個事務(wù)對數(shù)據(jù)進(jìn)?了修改,這時候兩次讀取的數(shù)據(jù)是不?致的?;米x:第?個事務(wù)查詢?定范圍內(nèi)的數(shù)據(jù),第?個事務(wù)在這個范圍insert?條數(shù)據(jù),這時候第?個事務(wù)會出現(xiàn)兩次查詢結(jié)果不?致的情況??偨Y(jié):隔離級別越?,越能保證數(shù)據(jù)的完整性和?致性,但是對并發(fā)性能的影響也越??多數(shù)的數(shù)據(jù)庫默認(rèn)隔離級別為ReadCommited,?如SqlServer、Oracle少數(shù)數(shù)據(jù)庫默認(rèn)隔離級別為:RepeatableRead如MySQL的InnoDB引擎(值得注意的是MySQLInnoDB引擎下的RR隔離級別已經(jīng)通過next-keylock解決了幻讀問題)Spring中的事務(wù)隔離級別@Transactional注解中可以設(shè)置事務(wù)的隔離級別,默認(rèn)是ISOLATION_DEFAULT級別。由屬性接?TransactionDefinition可以看到,可返回四個基本事務(wù)屬性:publicinterfaceTransactionDefinition{intgetPropagationBehavior();//傳播?為。intgetIsolationLevel();//隔離級別。事務(wù)管理器根據(jù)它來控制另外?個事務(wù)可以看到本事務(wù)內(nèi)的哪些數(shù)據(jù)。intgetTimeout();//事務(wù)必須在多少秒內(nèi)完成。booleanisReadOnly();//事務(wù)是否只讀。事務(wù)管理器能夠根據(jù)這個返回值進(jìn)?優(yōu)化,確保事務(wù)是只讀的}事務(wù)的嵌套通過上?的理論知識的鋪墊,我們?致知道了數(shù)據(jù)庫事務(wù)和spring事務(wù)的?些屬性和特點,接下來我們通過分析?些嵌套事務(wù)的場景,來深?理解spring事務(wù)傳播的機(jī)制。假設(shè)外層事務(wù)ServiceA的MethodA()調(diào)?內(nèi)層ServiceB的MethodB()PROPAGATION_REQUIRED(Spring默認(rèn))如果ServiceB.methodB()的事務(wù)級別定義為PROPAGATION_REQUIRED,那么執(zhí)?ServiceA.methodA()的時候Spring已經(jīng)起了事務(wù),這時調(diào)?ServiceB.methodB(),ServiceB.methodB()看到??已經(jīng)運?在ServiceA.methodA()的事務(wù)內(nèi)部,就不再起新的事務(wù)。假如ServiceB.methodB()運?的時候發(fā)現(xiàn)??沒有在事務(wù)中,他就會為??分配?個事務(wù)。這樣,在ServiceA.methodA()或者在ServiceB.methodB()內(nèi)的任何地?出現(xiàn)異常,事務(wù)都會被回滾。PROPAGATION_REQUIRES_NEW?如我們設(shè)計ServiceA.methodA()的事務(wù)級別為PROPAGATION_REQUIRED,ServiceB.methodB()的事務(wù)級別為PROPAGATION_REQUIRES_NEW。那么當(dāng)執(zhí)?到ServiceB.methodB()的時候,ServiceA.methodA()所在的事務(wù)就會掛起,ServiceB.methodB()會起?個新的事務(wù),等待ServiceB.methodB()的事務(wù)完成以后,它才繼續(xù)執(zhí)?。它與PROPAGATION_REQUIRED的事務(wù)區(qū)別在于事務(wù)的回滾程度了。因為ServiceB.methodB()是新起?個事務(wù),那么就是存在兩個不同的事務(wù)。如果ServiceB.methodB()已經(jīng)提交,那么ServiceA.methodA()失敗回滾,ServiceB.methodB()是不會回滾的。如果ServiceB.methodB()失敗回滾,如果他拋出的異常被ServiceA.methodA()捕獲,ServiceA.methodA()事務(wù)仍然可能提交(主要看B拋出的異常是不是A會回滾的異常)。PROPAGATION_SUPPORTS假設(shè)ServiceB.methodB()的事務(wù)級別為PROPAGATION_SUPPORTS,那么當(dāng)執(zhí)?到ServiceB.methodB()時,如果發(fā)現(xiàn)ServiceA.methodA()已經(jīng)開啟了?個事務(wù),則加?當(dāng)前的事務(wù),如果發(fā)現(xiàn)ServiceA.methodA()沒有開啟事務(wù),則??也不開啟事務(wù)。這種時候,內(nèi)部?法的事務(wù)性完全依賴于最外層的事務(wù)。PROPAGATION_NESTED現(xiàn)在的情況就變得?較復(fù)雜了,ServiceB.methodB()的事務(wù)屬性被配置為PROPAGATION_NESTED,此時兩者之間?將如何協(xié)作呢?ServiceB#methodB如果rollback,那么內(nèi)部事務(wù)(即ServiceB#methodB)將回滾到它執(zhí)?前的SavePoint?外部事務(wù)(
溫馨提示
- 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版城市更新回遷協(xié)議范本(含產(chǎn)權(quán)過戶)3篇
- 二零二五年度針對乙方利益最大化的倉儲設(shè)施租賃協(xié)議3篇
- 二零二五版?zhèn)€人住房貸款貸款資料保存及保密協(xié)議3篇
- 2024版臨時設(shè)施租賃合同(建筑工地用)
- 二零二五年度知識產(chǎn)權(quán)質(zhì)押擔(dān)保合同模板匯編及操作流程3篇
- 2025年度教育機(jī)構(gòu)租賃合同關(guān)于設(shè)施設(shè)備維護(hù)的補充協(xié)議2篇
- 武漢晴川學(xué)院《性別、婚姻與家庭》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五年度企業(yè)資產(chǎn)剝離合同
- 2024版洗衣機(jī)銷售合同模板范本
- 二零二五版房地產(chǎn)項目投資合作框架協(xié)議范本剖析6篇
- 服務(wù)經(jīng)營培訓(xùn)課件ppt 老客戶經(jīng)營綜合版
- MT/T 199-1996煤礦用液壓鉆車通用技術(shù)條件
- GB/T 6144-1985合成切削液
- GB/T 10357.1-2013家具力學(xué)性能試驗第1部分:桌類強度和耐久性
- 第三方在線糾紛解決機(jī)制(ODR)述評,國際商法論文
- 公寓de全人物攻略本為個人愛好而制成如需轉(zhuǎn)載注明信息
- 第5章-群體-團(tuán)隊溝通-管理溝通
- 腎臟病飲食依從行為量表(RABQ)附有答案
- 深基坑-安全教育課件
- 園林施工管理大型園林集團(tuán)南部區(qū)域養(yǎng)護(hù)標(biāo)準(zhǔn)圖例
- 排水許可申請表
評論
0/150
提交評論