全面分析報(bào)告Spring地編程式事務(wù)管理系統(tǒng)及聲明式事務(wù)管理系統(tǒng)_第1頁(yè)
全面分析報(bào)告Spring地編程式事務(wù)管理系統(tǒng)及聲明式事務(wù)管理系統(tǒng)_第2頁(yè)
全面分析報(bào)告Spring地編程式事務(wù)管理系統(tǒng)及聲明式事務(wù)管理系統(tǒng)_第3頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、開始之前關(guān)于本教程本教程將深入講解Spring簡(jiǎn)單而強(qiáng)大的事務(wù)管理功能,包括編程式事務(wù)和聲明 式事務(wù)。通過(guò)對(duì)本教程的學(xué)習(xí),您將能夠理解Spring事務(wù)管理的本質(zhì),并靈活 運(yùn)用之。先決條件本教程假定您已經(jīng)掌握了 Java基礎(chǔ)知識(shí),并對(duì)Spring有一定了解。您還需要 具備基本的事務(wù)管理的知識(shí),比如:事務(wù)的定義,隔離級(jí)別的概念,等等。本文 將直接使用這些概念而不做詳細(xì)解釋。另外,您最好掌握數(shù)據(jù)庫(kù)的基礎(chǔ)知識(shí),雖然這不是必須。系統(tǒng)需求要試驗(yàn)這份教程中的工具和示例,硬件配置需求為:至少帶有512MB內(nèi)存(推薦1GB)的系統(tǒng)。需要安裝以下軟件:* Sun JDK 5.0 或更新版本或 IBM Develo

2、per Kit for the Java 5 platform版本。* Spring framework 2.5。本教程附帶的示例代碼已經(jīng)在 上測(cè)試過(guò)。* MySQL 5.0或更新版本。Spring事務(wù)屬性分析事務(wù)管理對(duì)于企業(yè)應(yīng)用而言至關(guān)重要。它保證了用戶的每一次操作都是可靠的, 即便出現(xiàn)了異常的訪問(wèn)情況,也不至于破壞后臺(tái)數(shù)據(jù)的完整性。就像銀行的自助 取款機(jī),通常都能正常為客戶服務(wù),但是也難免遇到操作過(guò)程中機(jī)器突然出故障 的情況,此時(shí),事務(wù)就必須確保出故障前對(duì)賬戶的操作不生效,就像用戶剛才完全沒(méi)有使用過(guò)取款機(jī)一樣,以保證用戶和銀行的利益都不受損失。在Spring 中,事務(wù)是通過(guò) Transac

3、tionDefinition接口來(lái)定義的。該接口包含與事務(wù)屬性有關(guān)的方法。具體如清單1所示:清單1. Tran sactio nDefini tio n接口中定義的主要方法public in terface Tran sact ion Defi niti onint getIsolationLevel();int getPropagati on Behavior();int getTimeout();boolea n isRead Only();也許你會(huì)奇怪,為什么接口只提供了獲取屬性的方法, 而沒(méi)有提供相關(guān)設(shè)置屬性 的方法。其實(shí)道理很簡(jiǎn)單,事務(wù)屬性的設(shè)置完全是程序員控制的,因此程序員可 以自

4、定義任何設(shè)置屬性的方法,而且保存屬性的字段也沒(méi)有任何要求。 唯一的要 求的是,Spring進(jìn)行事務(wù)操作的時(shí)候,通過(guò)調(diào)用以上接口提供的方法必須能夠 返回事務(wù)相關(guān)的屬性取值。事務(wù)隔離級(jí)別隔離級(jí)別是指若干個(gè)并發(fā)的事務(wù)之間的隔離程度。Tran sactio nDefin ition接口中定義了五個(gè)表示隔離級(jí)別的常量: TransactionDefinitionSOLATION_DEFAULT :這是默認(rèn)值,表示使用底層數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。對(duì)大部分?jǐn)?shù)據(jù)庫(kù)而言,通常這值就是Tran sactio nDefin iti onSOLATION_READ_COMMITTED。 Tran sactio nDef

5、i ni tio nSOLATION_READ_UNCOMMITTED 該隔離級(jí)別表示一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)修改但還沒(méi)有提交的數(shù)據(jù)。該級(jí)別不能防止臟讀和不可重復(fù)讀,因此很少使用該隔離級(jí)別。 TransactionDefinitionSOLATION_READ_COMMITTED 該隔離級(jí)別表示一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)。該級(jí)別可以防止臟讀,這也是大多數(shù)情況下的推薦值。 TransactionDefinitionSOLATION_REPEATABLE_READ:該隔離級(jí)別表示一個(gè)事務(wù)在整個(gè)過(guò)程中可以多次重復(fù)執(zhí)行某個(gè)查詢,并且每次返回的記錄都相同。即使在多次查詢之間有新增的數(shù)據(jù)滿

6、足該查詢,這些新增的記錄也會(huì)被忽略。該級(jí)別 可以防止臟讀和不可重復(fù)讀。 Tran sactio nDefin itio nSOLATION_SERIALIZABLE :所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說(shuō),該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會(huì)用到該級(jí)別。事務(wù)傳播行為所謂事務(wù)的傳播行為是指,如果在開始當(dāng)前事務(wù)之前,一個(gè)事務(wù)上下文已經(jīng)存在, 此時(shí)有若干選項(xiàng)可以指定一個(gè)事務(wù)性方法的執(zhí)行行為。在Tran sactio nDefi niti on定義中包括了如下幾個(gè)表示傳播行為的常量: TransactionDefinitio

7、n.PROPAGATION_REQUIRED 如果當(dāng)前存在事務(wù),則加入該 事務(wù);如果當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)。 Tran sactio nDefini tio n.PROPAGATION_REQUIRES_NEW創(chuàng)建一個(gè)新的事務(wù),如果 當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。 TransactionDefinition.PROPAGATION_SUPPORTS 如果當(dāng)前存在事務(wù),則加入該 事務(wù);如果當(dāng)前沒(méi)有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。 Tran sactio nDefini tio n.PROPAGATION_NOT_SUPPORTED以非事務(wù)方式運(yùn)行,女口 果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛

8、起。 TransactionDefinition.PROPAGATION_NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存 在事務(wù),則拋出異常。 Tran sactio nDefini tio n.PROPAGATION_MANDATORY 如果當(dāng)前存在事務(wù),則加入 該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則拋出異常。 TransactionDefinition.PROPAGATION_NESTED:如果當(dāng)前存在事務(wù),則創(chuàng)建一個(gè) 事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來(lái)運(yùn)行;如果當(dāng)前沒(méi)有事務(wù),則該取值等價(jià)于Tran sactio nDefi nitio n.PROPAGATION_REQUIRED這里需要指出的是,前面的六種事

9、務(wù)傳播行為是Spring從EJB中引入的,他們共享相同的概念。而PROPAGATION_NEST是區(qū)pri ng 所特有的。以 PROPAGATION_NEST啟動(dòng)的事務(wù)內(nèi)嵌于外部事務(wù)中(如果存在外部事務(wù)的話), 此時(shí),內(nèi)嵌事務(wù)并不是一個(gè)獨(dú)立的事務(wù),它依賴于外部事務(wù)的存在,只有通過(guò)外部的事務(wù)提交,才能引起內(nèi)部事務(wù)的提交,嵌套的子事務(wù)不能單獨(dú)提交。如果熟 悉JDBC中的保存點(diǎn)(SavePoint)的概念,那嵌套事務(wù)就很容易理解了,其實(shí) 嵌套的子事務(wù)就是保存點(diǎn)的一個(gè)應(yīng)用, 一個(gè)事務(wù)中可以包括多個(gè)保存點(diǎn),每一個(gè) 嵌套子事務(wù)。另外,外部事務(wù)的回滾也會(huì)導(dǎo)致嵌套子事務(wù)的回滾。事務(wù)超時(shí)所謂事務(wù)超時(shí),就是指一

10、個(gè)事務(wù)所允許執(zhí)行的最長(zhǎng)時(shí)間,如果超過(guò)該時(shí)間限制但事務(wù)還沒(méi)有完成,則自動(dòng)回滾事務(wù)。在TransactionDefinition中以int 的值來(lái)表示超時(shí)時(shí)間,其單位是秒。事務(wù)的只讀屬性事務(wù)的只讀屬性是指,對(duì)事務(wù)性資源進(jìn)行只讀操作或者是讀寫操作。所謂事務(wù)性 資源就是指那些被事務(wù)管理的資源,比如數(shù)據(jù)源、JMS資源,以及自定義的事務(wù)性資源等等。如果確定只對(duì)事務(wù)性資源進(jìn)行只讀操作, 那么我們可以將事務(wù)標(biāo) 志為只讀的,以提高事務(wù)處理的性能。在TransactionDefinition中以boolean類型來(lái)表示該事務(wù)是否只讀。事務(wù)的回滾規(guī)則通常情況下,如果在事務(wù)中拋出了未檢查異常(繼承自RuntimeEx

11、ception 的異 常),則默認(rèn)將回滾事務(wù)。如果沒(méi)有拋出任何異常,或者拋出了已檢查異常,則 仍然提交事務(wù)。這通常也是大多數(shù)開發(fā)者希望的處理方式,也是EJB中的默認(rèn)處理方式。但是,我們可以根據(jù)需要人為控制事務(wù)在拋出某些未檢查異常時(shí)任然 提交事務(wù),或者在拋出某些已檢查異常時(shí)回滾事務(wù)。Spring事務(wù)管理API分析Spring框架中,涉及到事務(wù)管理的API大約有100個(gè)左右,其中最重要的有三 個(gè): Tra nsacti on Defi niti on、PlatformTra nsactio nMan ager 、Tra nsactio nStatus 。所謂事務(wù)管理,其實(shí)就是“按照給定的事務(wù)規(guī)則來(lái)

12、執(zhí)行提交或者回滾操作”。“給定的事務(wù)規(guī)則”就是用Tran sactio nDefi niti on表示的,“按照來(lái)執(zhí)行提交或者回滾操作”便是用 PlatformTra nsactio nMan ager來(lái)表示,而Transaction Status用于表示一個(gè)運(yùn)行著的事務(wù)的狀態(tài)。打一個(gè)不恰當(dāng)?shù)谋扔?,Tran sactio nDefin itio n與Tran sactio nStatus的關(guān)系就像程序和進(jìn)程的關(guān)系。Tran sacti on Def.該接口在前面已經(jīng)介紹過(guò),它用于定義一個(gè)事務(wù)。它包含了事務(wù)的靜態(tài)屬性,比 如:事務(wù)傳播行為、超時(shí)時(shí)間等等。Spring為我們提供了一個(gè)默認(rèn)的實(shí)現(xiàn)類:

13、DefaultTra nsactio nDefi ni tion,該類適用于大多數(shù)情況。如果該類不能滿足需求,可以通過(guò)實(shí)現(xiàn) TransactionDefinition接口來(lái)實(shí)現(xiàn)自己的事務(wù)定義。PlatformTra ns.PlatformTransactionManager用于執(zhí)行具體的事務(wù)操作。接口定義如清單 2所示:清單2. PlatformTransactionManager接口中定義的主要方法Public in terface PlatformTra nsactio nMan agerTran sactio nStatus getTra nsactio n(Tran sactio nD

14、efi nitio n defi niti on)throws Tran sact ion Excepti on;void commit(Tra nsactio nStatus status)throws Tran sacti on Excepti on;void rollback(Tra nsactio nStatus status)throwsTran sacti on Exceptio n;根據(jù)底層所使用的不同的持久化 API或框架,PlatformTransactionManager的主要實(shí)現(xiàn)類大致如下:* DataSourceTransactionManager :適用于使用JDBC

15、和iBatis 進(jìn)行數(shù)據(jù)持久化操 作的情況。« HibernateTransactionManager :適用于使用Hibernate進(jìn)行數(shù)據(jù)持久化操作的 情況。* JpaTransactionManager :適用于使用JPA進(jìn)行數(shù)據(jù)持久化操作的情況 * 另外還有 JtaTransactionManager 、JdoTransactionManager、JmsTransactionManager 等等。如果我們使用JTA進(jìn)行事務(wù)管理,我們可以通過(guò) JNDI和Spring的JtaTransactionManager 來(lái)獲取一個(gè)容器管理的 DataSource。JtaTransacti

16、onManager 不需要知道DataSource和其他特定的資源,因?yàn)樗鼘?使用容器提供的全局事務(wù)管理。而對(duì)于其他事務(wù)管理器,比如DataSourceTransactionManager,在定義時(shí)需要提供底層的數(shù)據(jù)源作為其屬性, 也就是 DataSource。與 HibernateTransactionManager對(duì)應(yīng)的是SessionFactory,與 JpaTransactionManager 對(duì)應(yīng)的是 EntityManagerFactory 等等。Tran sactio nStatusPlatformTransactionManager.getTransaction()方法返回一個(gè)

17、TransactionStatus對(duì)象。返回的TransactionStatus對(duì)象可能代表一個(gè)新的或已經(jīng)存在的事務(wù)(如果在當(dāng)前調(diào)用堆棧有一個(gè)符合條件的事務(wù))。Tran sacti on Status接口提供了一個(gè)簡(jiǎn)單的控制事務(wù)執(zhí)行和查詢事務(wù)狀態(tài)的方法。該接口定義如清單3所示:清單3. TransactionStatus接口中定義的主要方法publicin terface Tran sacti on Statusboolea n isNewTra nsact ion();void setRollback On ly();boolean isRollbackOn ly();編程式事務(wù)管理Spri

18、 ng的編程式事務(wù)管理概述在Spring出現(xiàn)以前,編程式事務(wù)管理對(duì)基于POJO的應(yīng)用來(lái)說(shuō)是唯一選擇。用 過(guò)Hibernate 的人都知道,我們需要在代碼中顯式調(diào)用begi nTran sactio n()、commit()、rollback。等事務(wù)管理相關(guān)的方法,這就是編程式事務(wù)管理。通過(guò) Spring提供的事務(wù)管理API,我們可以在代碼中靈活控制事務(wù)的執(zhí)行。在底層, Spring仍然將事務(wù)操作委托給底層的持久化框架來(lái)執(zhí)行?;诘讓覣PI的編程式事務(wù)管理根據(jù) PlatformTransactionManager 、 TransactionDefinition和TransactionStatus

19、三個(gè)核心接口,我們完全可以通過(guò)編程的方式來(lái)進(jìn)行事務(wù)管理。示例代碼如清單4所示:清單4.基于底層API的事務(wù)管理示例代碼public class Ban kServiceImpl impleme nts Ban kService private Ban kDao ban kDao;private TransactionDefinition txDefinition;private PlatformTra nsact ionMan ager txMa nager;public boolean transfer(Long fromId , Long toId , double amount) Tra

20、n sactio nStatus txStatus = txMa nager.getTra nsactio n( txDefi nitio n); boolea n result = false;try result = bankDao.transfer(fromld, toId , amount);txMa mit(txStatus); catch (Excepti on e) result = false;txMa nager.rollback(txStatus);return result;相應(yīng)的配置文件如清單5所示:清單5.基于底層API的事務(wù)管理示例配置文件<bea n id=

21、"ba nkService"vproperty n ame="ba nkDao" ref="ba nkDao"/><property n ame="txMa nager" ref="tra nsactio nMan ager"/><property n ame="txDefi niti on"><bea nn iti on "><property n ame="propagati on BehaviorNam

22、e" value="PROPAGATION_REQUIRED"/></bea n></property></bea n>如上所示,我們?cè)陬愔性黾恿藘蓚€(gè)屬性:一個(gè)是 Tran sactio nDefi ni tion類型的屬性,它用于定義一個(gè)事務(wù);另一個(gè)是PlatformTransactionManager 類型的 屬性,用于執(zhí)行事務(wù)管理操作。如果方法需要實(shí)施事務(wù)管理,我們首先需要在方法開始執(zhí)行前啟動(dòng)一個(gè)事務(wù),調(diào)用 PlatformTransactionManager.getTransaction()方法便可啟動(dòng)一個(gè)事務(wù)。創(chuàng)

23、建并啟動(dòng)了事務(wù)之后,便可以開始編寫業(yè)務(wù)邏輯代碼,然后在適當(dāng)?shù)牡胤?執(zhí)行事務(wù)的提交或者回滾?;赥ran sactio nTemplate的編程式事務(wù)管理通過(guò)前面的示例可以發(fā)現(xiàn),這種事務(wù)管理方式很容易理解,但令人頭疼的是,事 務(wù)管理的代碼散落在業(yè)務(wù)邏輯代碼中,破壞了原有代碼的條理性,并且每一個(gè)業(yè)務(wù)方法都包含了類似的啟動(dòng)事務(wù)、提交/回滾事務(wù)的樣板代碼。幸好,Spring也意識(shí)到了這些,并提供了簡(jiǎn)化的方法,這就是Spring在數(shù)據(jù)訪問(wèn)層非常常見的 模板回調(diào)模式。如清單6所示:清單6.基于TransactionTemplate的事務(wù)管理示例代碼public class Ban kServicelmpl

24、 impleme nts Ban kService private Ban kDao ban kDao;private Tran sactio nTemplate tran sact ion Template;public boolean transfer(finalLong fromId,final Long toId ,final doubleamount) retur n (Boolea n) tran sacti on Template.execute( newTran sactio nCallback()public Object dolnTran sact ion(Tran sac

25、ti on Status status) Object result;try result = bankDao.transfer(fromld, toId , amount); catch (Excepti on e) status.setRollbackO nl y();result = false;return result;);相應(yīng)的XML配置如下:清單7.基于Tran sactio nTemplate的事務(wù)管理示例配置文件<bea n id="ba nkService"><property n ame="ba nkDao" re

26、f="ba nkDao"/>vproperty n ame="tra nsactio nTemplate" ref="tra nsacti on Template"/v/bea n>TransactionTemplate 的 execute。方法有一個(gè) TransactionCallback類型的參數(shù),該接口中定義了一個(gè) dol nTran sactio n()方法,通常我們以匿名內(nèi)部類的方式實(shí)現(xiàn)TransactionCallback接口,并在其doInTransaction()方法中書寫業(yè)務(wù)邏輯代碼。這里可以使用默認(rèn)的事

27、務(wù)提交和回滾規(guī)則,這樣在業(yè)務(wù)代碼中就不需要顯式調(diào)用任何事務(wù)管理的API。doInTransaction()方法有一個(gè)Tran sactio nStatus類型的參數(shù),我們可以在方法的任何位置調(diào)用該參數(shù)的setRollbackO nly()方法將事務(wù)標(biāo)識(shí)為回滾的,以執(zhí)行事務(wù)回滾。根據(jù)默認(rèn)規(guī)則,如果在執(zhí)行回調(diào)方法的過(guò)程中拋出了未檢查異常, 或者顯式調(diào)用 了 TransacationStatus.setRollbackOnly()方法,則回滾事務(wù);如果事務(wù)執(zhí)行完成或者拋出了 checked類型的異常,則提交事務(wù)。Tran sactio nCallback接口有一個(gè)子接口 Tran sactio nC

28、allbackWithoutResult該接口中定義了一個(gè) doInTransactionWithoutResult()方法,Tran sactio nCallbackWithoutResult接口主要用于事務(wù)過(guò)程中不需要返回值的情況。當(dāng)然,對(duì)于不需要返回值的情況,我們?nèi)匀豢梢允褂肨ransactionCallback 接口,并在方法中返回任意值即可。聲明式事務(wù)管理Spring的聲明式事務(wù)管理概述Spring的聲明式事務(wù)管理在底層是建立在 AOP的基礎(chǔ)之上的。其本質(zhì)是對(duì)方法 前后進(jìn)行攔截,然后在目標(biāo)方法開始之前創(chuàng)建或者加入一個(gè)事務(wù), 在執(zhí)行完目標(biāo) 方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。聲明式事

29、務(wù)最大的優(yōu)點(diǎn)就是不需要通過(guò)編程的方式管理事務(wù),這樣就不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼,只需在配置文件中做相關(guān)的事務(wù)規(guī)則聲明(或通過(guò)等價(jià)的基于標(biāo)注的方式),便可以將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中。 因?yàn)?事務(wù)管理本身就是一個(gè)典型的橫切邏輯, 正是AOP的用武之地。Spring開發(fā)團(tuán) 隊(duì)也意識(shí)到了這一點(diǎn),為聲明式事務(wù)提供了簡(jiǎn)單而強(qiáng)大的支持。聲明式事務(wù)管理曾經(jīng)是EJB引以為傲的一個(gè)亮點(diǎn),如今 Spring 讓POJO在事 務(wù)管理方面也擁有了和EJB 一樣的待遇,讓開發(fā)人員在EJB容器之外也用上了 強(qiáng)大的聲明式事務(wù)管理功能,這主要得益于Spring依賴注入容器和SpringAOP的支持。依賴注入容器

30、為聲明式事務(wù)管理提供了基礎(chǔ)設(shè)施,使得Bean對(duì)于Spring框架而言是可管理的;而 Spring AOP則是聲明式事務(wù)管理的直接實(shí)現(xiàn) 者,這一點(diǎn)通過(guò)清單8可以看出來(lái)。通常情況下,筆者強(qiáng)烈建議在開發(fā)中使用聲明式事務(wù),不僅因?yàn)槠浜?jiǎn)單,更主要是因?yàn)檫@樣使得純業(yè)務(wù)代碼不被污染,極大方便后期的代碼維護(hù)。和編程式事務(wù)相比,聲明式事務(wù)唯一不足地方是,后者的最細(xì)粒度只能作用到方 法級(jí)別,無(wú)法做到像編程式事務(wù)那樣可以作用到代碼塊級(jí)別。 但是即便有這樣的 需求,也存在很多變通的方法,比如,可以將需要進(jìn)行事務(wù)管理的代碼塊獨(dú)立為下面就來(lái)看看Spring為我們提供的聲明式事務(wù)管理功能?;赥ran sactio nln

31、 ter.的聲明式事務(wù)管理最初,Spring提供了 Transactionlnterceptor類來(lái)實(shí)施聲明式事務(wù)管理功能先看清單8的配置文件:清單8.基于Tran sactio nln terceptor的事務(wù)管理示例配置文件<bea ns.><bean id="transactionlnterceptor"class="org.spri ngframework.tra nsactio n.i nterceptor.Tra nsactio nln terce ptor"><property n ame="tra

32、nsactio nMan ager" ref="tra nsactio nMan ager"/><property n ame="tra nsactio nAttributes"><props><prop key="tra nsfer">PROPAGATION_REQUIRED</prop></props></property></bea n><bea n id="ba nkServiceTarget"<

33、property n ame="ba nkDao" ref="ba nkDao"/></bea n><bea n id="ba nkService"<property n ame="target" ref="ba nkServiceTarget"/<property n ame="i nterceptorNames"><list><idref bea n="tra nsactio nln terceptor

34、"/></list></property></bea n>v/bea ns>首先,我們配置了一個(gè)Transactionlnterceptor來(lái)定義相關(guān)的事務(wù)規(guī)則,他有兩個(gè)主要的屬性:一個(gè)是tran sactio nMan ager ,用來(lái)指定一個(gè)事務(wù)管理器,并 將具體事務(wù)相關(guān)的操作委托給它;另一個(gè)是Properties 類型的tran sacti on Attributes屬性,它主要用來(lái)定義事務(wù)規(guī)則, 該屬性的每一個(gè)鍵值對(duì)中,鍵指定的是方法名,方法名可以使用通配符,而值就表示相應(yīng)方法的所應(yīng) 用的事務(wù)屬性。指定事務(wù)屬性的取值有較復(fù)雜的規(guī)

35、則,這在Spring中算得上是一件讓人頭疼的 事。具體的書寫規(guī)則如下:傳播行為,隔離級(jí)別,只讀屬性,超時(shí)屬性不影響提交的異常, 導(dǎo)致回滾的異常傳播行為是唯一必須設(shè)置的屬性,其他都可以忽略,Spring為我們提供了合理的默認(rèn)值。傳播行為的取值必須以“ PROPAGATION.開頭,具體包括:PROPAGATION_MANDA、(PROPAGATION_NESTEIROPAGATION_NE、ER PROPAGATION_NOT_SUPPORTWPAGATION_REQUIRED PROPAGATION_REQUIRES_NEWOPAGATION_SUPPOR共七種取值。隔離級(jí)別的取值必須以“ I

36、SOLATION:'開頭,具體包括:ISOLATION_DEFAU、TISOLATION_READ_COMMITTLATION_READ_UNCOMMI、TEDISOLATION_REPEATABLE_F、YDLATION_SERIALIZABLE共五種取值。如果事務(wù)是只讀的,那么我們可以指定只讀屬性,使用“ read On ly ”指定。否則 我們不需要設(shè)置該屬性。超時(shí)屬性的取值必須以“ TIMEOUT'開頭后面跟一個(gè)int類型的值,表示超時(shí) 時(shí)間,單位是秒。不影響提交的異常是指,即使事務(wù)中拋出了這些類型的異常,事務(wù)任然正常提交。 必須在每一個(gè)異常的名字前面加上“ +”。異常

37、的名字可以是類名的一部分。比 如“ +RuntimeException ”、“ +tion ” 等等。導(dǎo)致回滾的異常是指,當(dāng)事務(wù)中拋出這些類型的異常時(shí),事務(wù)將回滾。必須在每 一個(gè)異常的名字前面加上“-”。異常的名字可以是類名的全部或者部分,比如“-RuntimeException ”、“ -tio n” 等等。以下是兩個(gè)示例:vproperty n ame="*Service">PROPAGATION_REQUIRD).LATION_READ_COMMITTTIMIEOUT_20+AbcException , +DefException , -HijException

38、 </property>以上表達(dá)式表示,針對(duì)所有方法名以 Service 結(jié)尾的方法,使用PROPAGATION_REQUIR|E務(wù)傳播行為,事務(wù)的隔離級(jí)別是 ISOLATION_READ_COMMITT超寸時(shí)間為 20 秒,當(dāng)事務(wù)拋出 AbcException 或 者DefException 類型的異常,則仍然提交,當(dāng)拋出HijException類型的異常時(shí)必須回滾事務(wù)。這里沒(méi)有指定"readOnly",表示事務(wù)不是只讀的。<property name="test">PROPAGATION_REQUIREDreadO nl yv

39、/property>以上表達(dá)式表示,針對(duì)所有方法名為test 的方法,使用PROPAGATION_REQUIRED 事務(wù)傳播行為,并且該事務(wù)是只讀的。除此之外,其他的屬性均使用默認(rèn)值。比 如,隔離級(jí)別和超時(shí)時(shí)間使用底層事務(wù)性資源的默認(rèn)值,并且當(dāng)發(fā)生未檢查異常,則回滾事務(wù),發(fā)生已檢查異常則仍提交事務(wù)。配置好了 TransactionInterceptor,我們還需要配置一個(gè) ProxyFactoryBean來(lái)組裝target 和advice。這也是典型的 Spring AOP 的做法。通過(guò) ProxyFactoryBean生成的代理類就是織入了事務(wù)管理邏輯后的目標(biāo)類。至此, 聲明式事務(wù)管理

40、就算是實(shí)現(xiàn)了。我們沒(méi)有對(duì)業(yè)務(wù)代碼進(jìn)行任何操作,所有設(shè)置均在配置文件中完成,這就是聲明式事務(wù)的最大優(yōu)點(diǎn)?;赥ran sactio nProxy.的聲明式事務(wù)管理前面的聲明式事務(wù)雖然好,但是卻存在一個(gè)非常惱人的問(wèn)題:配置文件太多。我們必須針對(duì)每一個(gè)目標(biāo)對(duì)象配置一個(gè)ProxyFactoryBean ;另外,雖然可以通過(guò)父子Bean的方式來(lái)復(fù)用Transactionlnterceptor的配置,但是實(shí)際的復(fù)用幾率也不高;這樣,加上目標(biāo)對(duì)象本身,每一個(gè)業(yè)務(wù)類可能需要對(duì)應(yīng)三個(gè) <bean/> 配置,隨著業(yè)務(wù)類的增多,配置文件將會(huì)變得越來(lái)越龐大,管理配置文件又成了 問(wèn)題。為了緩解這個(gè)問(wèn)題,Sp

41、ring為我們提供了 TransactionProxyFactoryBean ,用 于將 Transactioninterceptor 和 ProxyFactoryBean 的配置合二為一。女口清單 9所示:清單9.基于TransactionProxyFactoryBean的事務(wù)管理示例配置文件<beans>v/bea n><bea n id="ba nkService"class="org.spri ngframework.tra nsactio n.in terceptor.Tra nsactio nProxyFa ctoryBea n

42、"><property n ame="target" ref="ba nkServiceTarget"/><property n ame="tra nsactio nMan ager" ref="tra nsactio nMan ager"/><property n ame="tra nsactio nAttributes"><props><prop key="tra nsfer">PROPAGATI

43、ON_REQUIRED</prop></props></property></bea n>/bea ns如此一來(lái),配置文件與先前相比簡(jiǎn)化了很多。我們把這種配置方式稱為Spri ng經(jīng)典的聲明式事務(wù)管理。相信在早期使用Spring的開發(fā)人員對(duì)這種配置聲明式 事務(wù)的方式一定非常熟悉。但是,顯式為每一個(gè)業(yè)務(wù)類配置一個(gè) Tran sactio nProxyFactoryBea n 的做法將 使得代碼顯得過(guò)于刻板,為此我們可以使用自動(dòng)創(chuàng)建代理的方式來(lái)將其簡(jiǎn)化, 使 用自動(dòng)創(chuàng)建代理是純AOP知識(shí),請(qǐng)讀者參考相關(guān)文檔,不在此贅述?;趖x命名空間的聲明式事務(wù)管

44、理前面兩種聲明式事務(wù)配置方式奠定了Spring聲明式事務(wù)管理的基石。在此基礎(chǔ)上, Spring 2.x弓I入了 tx命名空間,結(jié)合使用aop命名空間,帶給開發(fā) 人員配置聲明式事務(wù)的全新體驗(yàn),配置變得更加簡(jiǎn)單和靈活。另外,得益于aop 命名空間的切點(diǎn)表達(dá)式支持,聲明式事務(wù)也變得更加強(qiáng)大。如清單10所示:清單10.基于tx的事務(wù)管理示例配置文件beans <bea n id="ba nkService"<property n ame="ba nkDao" ref="ba nkDao"/></bea n><

45、;tx:advice id="ba nkAdvice" tran sactio n-man ager="tra nsactio nMan ager"><tx:attributes><tx:method name="tra nsfer" propagatio n="REQUIRED"/></tx:attributes></tx:advice><aop:c on fig><aop:pointcut id="bankPointcut&quo

46、t; expression="execution(*.tra nsfer(.)"/><aop:advisor advice-ref="ba nkAdvice" poin tcut-ref="ba nkPo in tcut"/></aop:c on fig> </bea ns>如果默認(rèn)的事務(wù)屬性就能滿足要求,那么代碼簡(jiǎn)化為如清單11所示:清單11.簡(jiǎn)化后的基于<tx>的事務(wù)管理示例配置文件<beans><bea n id="ba nkService&quo

47、t;<property n ame="ba nkDao" ref="ba nkDao"/></bea n><tx:advice id="ba nkAdvice" tran sactio n-man ager="tra nsactio nMan ager"><aop:c on fig><aop:po in tcut id="ba nkPo in tcut"expressio n="executio n( *.tra nsfer(.)&

48、quot;/><aop:advisor advice-ref="ba nkAdvice" poin tcut-ref="ba nkPo in tcut"/> </aop:c on fig> </bea ns>由于使用了切點(diǎn)表達(dá)式,我們就不需要針對(duì)每一個(gè)業(yè)務(wù)類創(chuàng)建一個(gè)代理對(duì)象了。另外,如果配置的事務(wù)管理器 Bean的名字取值為“ transactionManager ”,則 我們可以省略<tx:advice> 的transaction-manager 屬性,因?yàn)樵搶傩缘哪J(rèn) 值即為“ transacti

49、onManager ”?;赥ra nsactio nal的聲明式事務(wù)管理除了基于命名空間的事務(wù)配置方式,Spring 2.x還引入了基于Annotation的方式,具體主要涉及 Transactional標(biāo)注。Transactional可以作用于接口、 接口方法、類以及類方法上。當(dāng)作用于類上時(shí),該類的所有public 方法將都具 有該類型的事務(wù)屬性,同時(shí),我們也可以在方法級(jí)別使用該標(biāo)注來(lái)覆蓋類級(jí)別的 定義。如清單12所示:清單12.基于Transactional的事務(wù)管理示例配置文件Tra nsactio nal(propagatio n = Propagatio n.REQUIRED)public boolean transfer(Long fromId, Long toId , double amount) return bankDao.

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論