<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 64,  comments - 9,  trackbacks - 0

    首先,我們配置了一個 TransactionInterceptor 來定義相關的事務規則,他有兩個主要的屬性:一個是 transactionManager,用來指定一個事務管理器,并將具體事務相關的操作委托給它;另一個是 Properties 類型的 transactionAttributes 屬性,它主要用來定義事務規則,該屬性的每一個鍵值對中,鍵指定的是方法名,方法名可以使用通配符,而值就表示相應方法的所應用的事務屬性。

      指定事務屬性的取值有較復雜的規則,這在 Spring 中算得上是一件讓人頭疼的事。具體的書寫規則如下:

    傳播行為 [,隔離級別] [,只讀屬性] [,超時屬性] [不影響提交的異常] [,導致回滾的異常]

      傳播行為是唯一必須設置的屬性,其他都可以忽略,Spring為我們提供了合理的默認值。

      傳播行為的取值必須以“PROPAGATION_”開頭,具體包括:PROPAGATION_MANDATORY、 PROPAGATION_NESTED、PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED、 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_SUPPORTS,共七種取值。

      隔離級別的取值必須以“ISOLATION_”開頭,具體包括:ISOLATION_DEFAULT、 ISOLATION_READ_COMMITTED、ISOLATION_READ_UNCOMMITTED、 ISOLATION_REPEATABLE_READ、ISOLATION_SERIALIZABLE,共五種取值。

      如果事務是只讀的,那么我們可以指定只讀屬性,使用“readOnly”指定。否則我們不需要設置該屬性。

      超時屬性的取值必須以“TIMEOUT_”開頭,后面跟一個int類型的值,表示超時時間,單位是秒。

      不影響提交的異常是指,即使事務中拋出了這些類型的異常,事務任然正常提交。必須在每一個異常的名字前面加上“+”。異常的名字可以是類名的一部分。比如“+RuntimeException”、“+tion”等等。

    導致回滾的異常是指,當事務中拋出這些類型的異常時,事務將回滾。必須在每一個異常的名字前面加上“-”。異常的名字可以是類名的全部或者部分,比如“-RuntimeException”、“-tion”等等。

      以下是兩個示例:

    <property name="*Service">
    PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20,
    +AbcException,+DefException,-HijException
    </property>

    以上表達式表示,針對所有方法名以 Service 結尾的方法,使用 PROPAGATION_REQUIRED 事務傳播行為,事務的隔離級別是 ISOLATION_READ_COMMITTED,超時時間為20秒,當事務拋出 AbcException 或者 DefException 類型的異常,則仍然提交,當拋出 HijException 類型的異常時必須回滾事務。這里沒有指定"readOnly",表示事務不是只讀的。

    <property name="test">PROPAGATION_REQUIRED,readOnly</property>

    以上表達式表示,針對所有方法名為 test 的方法,使用 PROPAGATION_REQUIRED 事務傳播行為,并且該事務是只讀的。除此之外,其他的屬性均使用默認值。比如,隔離級別和超時時間使用底層事務性資源的默認值,并且當發生未檢查異常,則回滾事務,發生已檢查異常則仍提交事務。

    配置好了 TransactionInterceptor,我們還需要配置一個 ProxyFactoryBean 來組裝 target 和advice。這也是典型的 Spring AOP 的做法。通過 ProxyFactoryBean 生成的代理類就是織入了事務管理邏輯后的目標類。至此,聲明式事務管理就算是實現了。我們沒有對業務代碼進行任何操作,所有設置均在配置文件中完成,這就是聲明式事務的最大優點。

    基于 TransactionProxy... 的聲明式事務管理

    前面的聲明式事務雖然好,但是卻存在一個非常惱人的問題:配置文件太多。我們必須針對每一個目標對象配置一個 ProxyFactoryBean;另外,雖然可以通過父子 Bean 的方式來復用 TransactionInterceptor 的配置,但是實際的復用幾率也不高;這樣,加上目標對象本身,每一個業務類可能需要對應三個 <bean/> 配置,隨著業務類的增多,配置文件將會變得越來越龐大,管理配置文件又成了問題。

      為了緩解這個問題,Spring 為我們提供了 TransactionProxyFactoryBean,用于將TransactionInterceptor 和 ProxyFactoryBean 的配置合二為一。如清單9所示:

      清單9. 基于 TransactionProxyFactoryBean 的事務管理示例配置文件

    <beans......>
    ......
    <bean id="bankServiceTarget"
    class="footmark.spring.core.tx.declare.classic.BankServiceImpl">
    <property name="bankDao" ref="bankDao"/>
    </bean>
    <bean id="bankService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="target" ref="bankServiceTarget"/>
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
    <props>
    <prop key="transfer">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>
    ......
    </beans>

    如此一來,配置文件與先前相比簡化了很多。我們把這種配置方式稱為 Spring 經典的聲明式事務管理。相信在早期使用 Spring 的開發人員對這種配置聲明式事務的方式一定非常熟悉。

    但是,顯式為每一個業務類配置一個 TransactionProxyFactoryBean 的做法將使得代碼顯得過于刻板,為此我們可以使用自動創建代理的方式來將其簡化,使用自動創建代理是純 AOP 知識,請讀者參考相關文檔,不在此贅述。

      基于 <tx> 命名空間的聲明式事務管理

    前面兩種聲明式事務配置方式奠定了 Spring 聲明式事務管理的基石。在此基礎上,Spring 2.x 引入了 <tx> 命名空間,結合使用 <aop> 命名空間,帶給開發人員配置聲明式事務的全新體驗,配置變得更加簡單和靈活。另外,得益于 <aop> 命名空間的切點表達式支持,聲明式事務也變得更加強大。

      如清單10所示:

      清單10. 基于 <tx> 的事務管理示例配置文件

    <beans......>
    ......
    <bean id="bankService"
    class="footmark.spring.core.tx.declare.namespace.BankServiceImpl">
    <property name="bankDao" ref="bankDao"/>
    </bean>
    <tx:advice id="bankAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="transfer" propagation="REQUIRED"/>
    </tx:attributes>
    </tx:advice>
    <aop:config>
    <aop:pointcut id="bankPointcut" expression="execution(* *.transfer(..))"/>
    <aop:advisor advice-ref="bankAdvice" pointcut-ref="bankPointcut"/>
    </aop:config>
    ......
    </beans>

    如果默認的事務屬性就能滿足要求,那么代碼簡化為如清單 11 所示:

      清單 11. 簡化后的基于 <tx> 的事務管理示例配置文件

    <beans......>
    ......
    <bean id="bankService"
    class="footmark.spring.core.tx.declare.namespace.BankServiceImpl">
    <property name="bankDao" ref="bankDao"/>
    </bean>
    <tx:advice id="bankAdvice" transaction-manager="transactionManager">
    <aop:config>
    <aop:pointcut id="bankPointcut" expression="execution(**.transfer(..))"/>
    <aop:advisor advice-ref="bankAdvice" pointcut-ref="bankPointcut"/>
    </aop:config>
    ......
    </beans>

    由于使用了切點表達式,我們就不需要針對每一個業務類創建一個代理對象了。另外,如果配置的事務管理器 Bean 的名字取值為“transactionManager”,則我們可以省略 <tx:advice> 的 transaction-manager 屬性,因為該屬性的默認值即為“transactionManager”。

      基于 @Transactional 的聲明式事務管理

      除了基于命名空間的事務配置方式,Spring 2.x 還引入了基于 Annotation 的方式,具體主要涉及@Transactional 標注。@Transactional 可以作用于接口、接口方法、類以及類方法上。當作用于類上時,該類的所有 public 方法將都具有該類型的事務屬性,同時,我們也可以在方法級別使用該標注來覆蓋類級別的定義。如清單12所示:

    清單12. 基于 @Transactional 的事務管理示例配置文件

    @Transactional(propagation = Propagation.REQUIRED)
    public boolean transfer(Long fromId, Long toId, double amount) {
    return bankDao.transfer(fromId, toId, amount);
    }

      Spring 使用 BeanPostProcessor 來處理 Bean 中的標注,因此我們需要在配置文件中作如下聲明來激活該后處理 Bean,如清單13所示:

      清單13. 啟用后處理Bean的配置

    <tx:annotation-driven transaction-manager="transactionManager"/>

      與前面相似,transaction-manager 屬性的默認值是 transactionManager,如果事務管理器 Bean 的名字即為該值,則可以省略該屬性。

    雖然 @Transactional 注解可以作用于接口、接口方法、類以及類方法上,但是 Spring 小組建議不要在接口或者接口方法上使用該注解,因為這只有在使用基于接口的代理時它才會生效。另外, @Transactional 注解應該只被應用到 public 方法上,這是由 Spring AOP 的本質決定的。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解,這將被忽略,也不會拋出任何異常。

    基于 <tx> 命名空間和基于 @Transactional 的事務聲明方式各有優缺點。基于 <tx> 的方式,其優點是與切點表達式結合,功能強大。利用切點表達式,一個配置可以匹配多個方法,而基于 @Transactional 的方式必須在每一個需要使用事務的方法或者類上用 @Transactional 標注,盡管可能大多數事務的規則是一致的,但是對 @Transactional 而言,也無法重用,必須逐個指定。另一方面,基于 @Transactional 的方式使用起來非常簡單明了,沒有學習成本。開發人員可以根據需要,任選其中一種使用,甚至也可以根據需要混合使用這兩種方式。

    如果不是對遺留代碼進行維護,則不建議再使用基于 TransactionInterceptor 以及基于TransactionProxyFactoryBean 的聲明式事務管理方式,但是,學習這兩種方式非常有利于對底層實現的理解。

    雖然上面共列舉了四種聲明式事務管理方式,但是這樣的劃分只是為了便于理解,其實后臺的實現方式是一樣的,只是用戶使用的方式不同而已。

      結束語

      本教程的知識點大致總結如下:

      基于 TransactionDefinition、PlatformTransactionManager、TransactionStatus 編程式事務管理是 Spring 提供的最原始的方式,通常我們不會這么寫,但是了解這種方式對理解 Spring 事務管理的本質有很大作用。

      基于 TransactionTemplate 的編程式事務管理是對上一種方式的封裝,使得編碼更簡單、清晰。

      基于 TransactionInterceptor 的聲明式事務是 Spring 聲明式事務的基礎,通常也不建議使用這種方式,但是與前面一樣,了解這種方式對理解 Spring 聲明式事務有很大作用。

      基于 TransactionProxyFactoryBean 的聲明式事務是上中方式的改進版本,簡化的配置文件的書寫,這是 Spring 早期推薦的聲明式事務管理方式,但是在 Spring 2.0 中已經不推薦了。

      基于 <tx> 和 <aop> 命名空間的聲明式事務管理是目前推薦的方式,其最大特點是與 Spring AOP 結合緊密,可以充分利用切點表達式的強大支持,使得管理事務更加靈活。

      基于 @Transactional 的方式將聲明式事務管理簡化到了極致。開發人員只需在配置文件中加上一行啟用相關后處理 Bean 的配置,然后在需要實施事務管理的方法或者類上使用 @Transactional 指定事務規則即可實現事務管理,而且功能也不必其他方式遜色
    posted on 2009-09-04 16:27 super_nini 閱讀(1640) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2009年9月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    常用鏈接

    留言簿

    隨筆檔案

    文章檔案

    相冊

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲免费一级视频| 超pen个人视频国产免费观看| 亚洲AV无码不卡在线观看下载| 国产亚洲精品拍拍拍拍拍| 国产亚洲Av综合人人澡精品| 成年在线网站免费观看无广告| 性xxxx黑人与亚洲| 成人毛片18女人毛片免费96| 精品亚洲AV无码一区二区三区 | 人体大胆做受免费视频| 四虎在线播放免费永久视频| 国产亚洲精品成人久久网站| 亚洲第一区精品观看| 污污污视频在线免费观看| 亚洲午夜福利精品无码| 国产91在线|亚洲| 在线jlzzjlzz免费播放| 久久久久亚洲AV无码专区体验| 手机永久免费的AV在线电影网| 亚洲精品亚洲人成在线观看下载 | 美女黄色免费网站| 亚洲一区无码精品色| 精品免费tv久久久久久久 | 亚洲精品成人网站在线观看| 国产成人人综合亚洲欧美丁香花| 114级毛片免费观看| 亚洲AV无码成人精品区天堂 | 亚洲国产一区二区三区| a级毛片免费在线观看| 亚洲精品动漫人成3d在线| a级毛片免费高清毛片视频| 亚洲一级毛片在线观| 又爽又高潮的BB视频免费看| 亚洲日韩av无码中文| 在线a级毛片免费视频| 亚洲成a人片在线不卡一二三区 | 乱人伦中文视频在线观看免费| 最近2019免费中文字幕6| 2020久久精品亚洲热综合一本 | 免费观看男人吊女人视频| 亚洲国产中文在线二区三区免|