Spring高級事務管理難點難點剖析_第1頁
Spring高級事務管理難點難點剖析_第2頁
Spring高級事務管理難點難點剖析_第3頁
Spring高級事務管理難點難點剖析_第4頁
Spring高級事務管理難點難點剖析_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、Spring高級事務管理難點剖析1-1:DAO和事務管理的牽絆 問題:問題: 很少使用Spring但不使用Spring事務管理器的應用,因此常常有人會問:是否用了Spring,就一定要用Spring事務管理器,否則就無法進行數(shù)據(jù)的持久化操作呢?事務管理器和DAO是什么關系呢?1-2:DAO和事務管理的牽絆 真相:真相: 答案當然是否定的!我們都知道:事務管理是保證數(shù)據(jù)操作的事務性(即原子性,一致性,隔離性,持久性,也即所謂的ACID),脫離了事務性,DAO照樣可以順利地進行數(shù)據(jù)的操作。2-1:應用分層的迷惑 問題:問題: Web,Service及DAO三層劃分就像西方國家的立法、行政、司法三權

2、分立一樣被奉為金科玉律,是否要使用Spring的事務管理就一定先要進行三層的劃分呢?是否每一層都需要有接口+實現(xiàn)類呢?2-2:應用分層的迷惑 真相:真相: 應用代碼分層和Spring的事務管理是兩回事,沒有應用分層照樣可以進行Spring事務管理。Spring的事務管理也不依賴于接口+實現(xiàn)類的開發(fā)模式。3-1:事務方法嵌套調(diào)用的迷茫 問題:問題: 一個事務方法調(diào)用另一個事務方法會產(chǎn)生兩個事務,還是只有一個事務?3-2 認識TransactionDefinitionlint getPropagationBehavior():事務的傳播行為lint getIsolationLevel():事務的隔

3、離級別lint getTimeout():事務的過期時間lboolean isReadOnly():事務的讀寫特性。很明顯,除了事務的傳播行為外,事務的其它特性Spring是借助底層資源的功能來完成的,Spring無非只充當個代理的角色。但是事務的傳播行為卻是Spring憑借自身的框架提供的功能3-3 Spring事務傳播行為lPROPAGATION_REQUIRED:如果當前沒有事務,就新建一個事務,如果已經(jīng)存在一個事務中,加入到這個事務中。這是最常見的選擇。lPROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行。lPROPAGATION_MANDAT

4、ORY:使用當前的事務,如果當前沒有事務,就拋出異常。lPROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。lPROPAGATION_NOT_SUPPORTED:以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。lPROPAGATION_NEVER:以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。lPROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行與PROPAGATION_REQUIRED類似的操作。所謂事務傳播行為就是多個事務方法相互調(diào)用時,事務如何在這些方法間傳播。Spring支持7種事務傳

5、播行為3-4:事務方法嵌套調(diào)用的迷茫 真相:真相: Spring默認的事務傳播行為是PROPAGATION_REQUIRED,它適合于絕大多數(shù)的情況。假設ServiveX#methodX()都工作在事務環(huán)境下(即都被Spring事務增強了),假設程序中存在如下的調(diào)用鏈:Service1#method1()-Service2#method2()-Service3#method3(),那么這3個服務類的3個方法通過Spring的事務傳播機制都工作在同一個事務中。4-1:多線程的困惑 問題:問題: 如果在一個ServiceA和a()方法中啟動一個線程,在這個新創(chuàng)建的線程中執(zhí)行ServiceB的事務方

6、法b(),ServiceA的a()方法和ServiceB的b()方法是工作在同一事務環(huán)境中,還是分別擁有一個獨立的事務呢?4-2:多線程的困惑 真相:真相: 在相同線程中進行相互嵌套調(diào)用的事務方法工作于相同的事務中。如果這些相互嵌套調(diào)用的方法工作在不同的線程中,不同線程下的事務方法工作在獨立的事務中。5-1:聯(lián)合軍種作戰(zhàn)的混亂 問題:問題: Hibernate,Spring JDBC,iBatis等多種數(shù)據(jù)持久方法如何聯(lián)合使用,會存在哪些問題,如何進行事務管理的配置?5-2:如何配置事務管理器 如果你采用了一個高端ORM技術(Hibernate,JPA,JDO),同時采用一個JDBC技術(Sp

7、ring JDBC,iBatis),由于前者的會話(Session)是對后者連接(Connection)的封裝,Spring會“足夠智能地”在同一個事務線程讓前者的會話封裝后者的連接。所以,我們只要直接采用前者的事務管理器就可以了。下表給出了混合數(shù)據(jù)訪問技術所對應的事務管理器: 5-3:丟失更新 由于Hibernate一級緩存的原因,在通過save,update,delete等方法操作數(shù)據(jù)時,并沒有真正向數(shù)據(jù)庫發(fā)送SQL,只有調(diào)用flush()時,Hibernate才會將一級緩存中的狀態(tài)變化同步到數(shù)據(jù)庫中。 Hibernate的事務管理在提交事務時,會自動調(diào)用flush()操作,將一級緩存同步

8、到數(shù)據(jù)庫中,此時才會將產(chǎn)生并向數(shù)據(jù)庫發(fā)送SQL語句。 正是因為以上原因的存在,所有在混合使用JDBC和Hibernate時,可能存在丟失更新的問題。Hibernate:user.setMark(30);session.update(user)JDBC:“update t_user set mark=mark+10”開始事務結束事務Hibernate同步一級緩存 1.“update t_user set mark=30” 2. 提交事務,最終user的mark為30,JDBC的更改被覆蓋5-4:緩存不同步 在混合使用Hibernate和JDBC時,JDBC的操作不會同步到Hibernate的緩存

9、中(一級緩存及二級緩存),Hibernate緩存中的狀態(tài)變更也不被JDBC感知。因此混合使用時必須特別關注這一點。5-5:混合使用最佳實踐 由于混合數(shù)據(jù)訪問技術的方案的事務同步而緩存不同步的情況,所以最好用Hibernate完成讀寫操作,而用Spring JDBC完成讀的操作。如用Spring JDBC進行簡要列表的查詢,而用Hibernate對查詢出的數(shù)據(jù)進行維護。如果確實要同時使用Hibernate和Spring JDBC讀寫數(shù)據(jù),則必須充分考慮到Hibernate緩存機制引發(fā)的問題:必須充分分析數(shù)據(jù)維護邏輯,根據(jù)需要,及時調(diào)用Hibernate的flush()方法,以免覆蓋Spring

10、JDBC的更改,在Spring JDBC更改數(shù)據(jù)庫時,維護Hibernate的緩存。6-1:特殊方法成漏網(wǎng)之魚 問題:問題: 是否配置了Spring事務AOP增強后,服務方法就可以工作在事務環(huán)境中呢?Spring的事務增強有哪些限制條件,哪些方法需要特別關注?6-2:特殊方法成漏網(wǎng)之魚真相:真相: 由于Spring事務管理是基于接口代理或動態(tài)字節(jié)碼技術,通過AOP實施事務增強的。 對于基于接口動態(tài)代理的AOP事務增強來說,由于接口的方法是public的,這就要求實現(xiàn)類的實現(xiàn)方法必須是public的(不能是protected,private等),同時不能使用static的修飾符。所以,可以實施接

11、口動態(tài)代理的方法只能是使用“public”或“public final”修飾符的方法,其它方法不可能被動態(tài)代理,相應的也就不能實施AOP增強,也即不能進行Spring事務增強了。 基于CGLib字節(jié)碼動態(tài)代理的方案是通過擴展被增強類,動態(tài)創(chuàng)建子類的方式進行AOP增強植入的。由于使用final,static,private修飾符的方法都不能被子類覆蓋,相應的,這些方法將不能被實施的AOP增強。所以,必須特別注意這些修飾符的使用,以免不小心成為事務管理的漏網(wǎng)之魚。7-1:數(shù)據(jù)連接泄漏 問題:問題: 是否使用Spring的事務管理后,就沒有數(shù)據(jù)連接泄漏的問題了?哪些情況下會發(fā)生連接泄漏問題,如何處理

12、?7-2:直接從數(shù)據(jù)源獲取連接 如果我們在事務上下文中直接從數(shù)據(jù)源直接獲取連接,且在使用完成后不主動歸還給數(shù)據(jù)源(調(diào)用Connection#close()),則將造成數(shù)據(jù)連接泄漏的問題。7-3:DataSourceUtils Spring提供了一個能從當前事務上下文中獲取綁定的數(shù)據(jù)連接的工具類,那就是DataSourceUtils。Spring強調(diào)必須使用DataSourceUtils工具類獲取數(shù)據(jù)連接。lstatic ConnectiondoGetConnection(DataSource dataSource):首先嘗試從事務上下文中獲取連接,失敗后再從數(shù)據(jù)源獲取連接;lstatic Co

13、nnectiongetConnection(DataSource dataSource):和doGetConnection方法的功能一樣,實際上,它內(nèi)部就是調(diào)用doGetConnection方法獲取連接的;lstatic voiddoReleaseConnection(Connection con, DataSource dataSource):釋放連接,放回到連接池中;lstatic voidreleaseConnection(Connection con, DataSource dataSource):和doReleaseConnection方法的功能一樣,實際上,它內(nèi)部就是調(diào)用doRel

14、easeConnection方法獲取連接的;7-4:DataSourceUtils內(nèi)部機制getConnectionif(工作在事務上下文,且上下文未綁定連接) 將此連接綁定到事務上下文if(事務上下文連接為空)getConnectiongetConnectionConnectionHolder:= getResource(dataSource)事務上下文管理器getConnection(DataSource dataSource)DataSourceUtilsTransactionSynchronizationManagerDataSource調(diào)用者ConnectionHolder事務上下文

15、線程綁定的連接if(工作在事務上下文,且上下文未綁定連接) 將此連接綁定到事務上下文if(事務上下文連接為空)getConnectiongetConnectionConnectionHolder:= getResource(dataSource)getConnection(DataSource dataSource)1.首先嘗試從事務上下文獲取連接2.如果事務上下文沒有連接,則直接從數(shù)據(jù)源獲取3.如果有事務上下文,將連接綁定上當前的事務上下文中。7-5:使用DataSourceUtils獲取數(shù)據(jù)連接也可能造成泄漏 如果DataSourceUtils在沒有事務上下文的方法中使用getConnection()獲取連接,依然會造成數(shù)據(jù)連接泄漏! 7-6:JdbcTemplate可以做到對連接泄漏免疫來看一下JdbcTemplate最核心的一個數(shù)

溫馨提示

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

評論

0/150

提交評論