我的java天地

          spring2.0 事務配置

          Spring 2.0 的事務配置主要有以下兩種方式,一種是聲明式事務配置,一種是編程式事務配置,這里主要介紹聲明式事務配置.
          使用Spring時,無論你選擇編程式還是聲明式的事務管理,定義一個正確的 PlatformTransactionManager 實現(xiàn)都是至關(guān)重要的。按照Spring的良好風格,這種重要定義都是通過IoC實現(xiàn)的。
          一般來說,選擇PlatformTransactionManager實現(xiàn)時需要知道當前的工作環(huán)境,如JDBC、JTA、Hibernate等。下面的例子來自Spring示例應用——jPetStore——中的dataAccessContext-local.xml文件,其中展示了一個局部PlatformTransactionManager實現(xiàn)是怎么定義的(僅限于純粹JDBC環(huán)境)
          我們必須先定義一個JDBC DataSource,然后使用Spring的DataSourceTransactionManager,并傳入指向DataSource的引用。
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          ??<property name="driverClassName" value="${jdbc.driverClassName}" />
          ??<property name="url" value="${jdbc.url}" />
          ??<property name="username" value="${jdbc.username}" />
          ??<property name="password" value="${jdbc.password}" />
          </bean>
          PlatformTransactionManager bean的定義如下:
          <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          ??<property name="dataSource" ref="dataSource"/>
          </bean>
          我們也可以很容易地使用Hibernate局部事務,就像下面的Spring框架的 PetClinic 示例應用中的例子一樣)。這種情況下,我們需要定義一個Hibernate的 LocalSessionFactoryBean,應用程序從中獲取到Hibernate Session 實例。
          DataSource 的bean定義同上例類似(這里不再展示)。不過,如果是一個JEE容器提供的 DataSource,它將由JEE容器自身,而不是Spring框架來管理事務。
          這種情況中'txManager' bean的類型為 HibernateTransactionManager。同樣地,DataSourceTransactionManager 需要一個指向 DataSource 的引用,而 HibernateTransactionManager 需要一個指向 SessionFactory 的引用。
          <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
          ??<property name="dataSource" ref="dataSource" />
          ??<property name="mappingResources">
          ????<list>
          ??????<value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
          ????</list>
          ??</property>
          ??<property name="hibernateProperties">
          ????<value>
          ??????????hibernate.dialect=${hibernate.dialect}
          ????????</value>
          ??</property>
          </bean>

          <bean id="txManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
          ??<property name="sessionFactory" ref="sessionFactory" />
          </bean>
          聲明式事務管理大多數(shù)Spring用戶選擇聲明式事務管理。這是對應用代碼影響最小的選擇,因此也最符合 非侵入式 輕量級容器的理念。
          Spring的聲明式事務管理是通過Spring AOP實現(xiàn)的,因為事務方面的代碼與Spring綁定并以一種樣板式風格使用,不過盡管如此,你一般并不需要理解AOP概念就可以有效地使用Spirng的聲明式事務管理。
          從考慮EJB CMT和Spring聲明式事務管理的相似以及不同之處出發(fā)是很有益的。它們的基本方法是相似的:都可以指定事務管理到單獨的方法;如果需要可以在事務上下文調(diào)用 setRollbackOnly() 方法。不同之處在于:
          ·???????? 不像EJB CMT綁定在JTA上,Spring聲明式事務管理可以在任何環(huán)境下使用。只需更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事務機制一起工作。
          ·???????? Spring的聲明式事務管理可以被應用到任何類(以及那個類的實例)上,不僅僅是像EJB那樣的特殊類。
          ·???????? Spring提供了聲明式的回滾規(guī)則:EJB沒有對應的特性,我們將在下面討論。回滾可以聲明式的控制,不僅僅是編程式的。
          ·???????? Spring允許你通過AOP定制事務行為。例如,如果需要,你可以在事務回滾中插入定制的行為。你也可以增加任意的通知,就象事務通知一樣。使用EJB CMT,除了使用setRollbackOnly(),你沒有辦法能夠影響容器的事務管理。
          ·???????? Spring不提供高端應用服務器提供的跨越遠程調(diào)用的事務上下文傳播。如果你需要這些特性,我們推薦你使用EJB。然而,不要輕易使用這些特性。通常我們并不希望事務跨越遠程調(diào)用。
          回滾規(guī)則的概念比較重要:它使我們能夠指定什么樣的異常(和throwable)將導致自動回滾。我們在配置文件中聲明式地指定,無須在Java代碼中。同時,我們?nèi)耘f可以通過調(diào)用 TransactionStatus 的 setRollbackOnly() 方法編程式地回滾當前事務。通常,我們定義一條規(guī)則,聲明 MyApplicationException 必須總是導致事務回滾。這種方式帶來了顯著的好處,它使你的業(yè)務對象不必依賴于事務設(shè)施。典型的例子是你不必在代碼中導入Spring API,事務等。
          對EJB來說,默認的行為是EJB容器在遇到 系統(tǒng)異常(通常指運行時異常)時自動回滾當前事務。EJB CMT遇到 應用異常(例如,除了 java.rmi.RemoteException 外別的checked exception)時并不會自動回滾。默認式Spring處理聲明式事務管理的規(guī)則遵守EJB習慣(只在遇到unchecked exceptions時自動回滾),但通常定制這條規(guī)則會更有用。
          列子:
          清單1:
          <?xml version="1.0" encoding="gb2312"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
          <beans>
          ????<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          ????????<property name="driverClassName" value="${jdbc.driverClassName}"/>
          ????????<property name="url" value="${jdbc.url}"/>
          ????????<property name="username" value="${jdbc.username}"/>
          ????????<property name="password" value="${jdbc.password}"/>
          ????</bean>
          ????
          ?? <!--Hibernate SessionFatory-->
          ????<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          ????????<property name="dataSource" ref="dataSource"/>
          ????????<property name="mappingDirectoryLocations">
          ????????????<list>
          ????????????????<value>classpath:com/sailing/domain/hbm/</value>
          ????????????</list>
          ????????</property>
          ????????<property name="hibernateProperties">
          ????????????<props>
          ????????????????<prop key="hibernate.dialect">${hibernate.dialect}</prop>
          ????????????????<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
          ????????????????<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
          ????????????????<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
          ????????????</props>
          ????????</property>
          ????</bean>


          ????<!--Hibernate TransactionManager-->
          ????<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          ????????<property name="sessionFactory" ref="sessionFactory"/>
          ????</bean>

          ????<!--
          ????<bean id="tocharFunction" class="com.sailing.framework.hibernate.TOCharFunction">
          ????????<property name="tocharFunction" value="{$hibernate.to_char_function}"/>
          ????</bean>
          ????-->
          </beans>
          清單2
          <?xml version="1.0" encoding="gb2312"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          ?????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          ?????? xmlns:aop="http://www.springframework.org/schema/aop"
          ?????? xmlns:tx="http://www.springframework.org/schema/tx"
          ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
          ?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
          ?????????? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
          ?????? default-autowire="byName" default-lazy-init="true">

          ????<!-- 支持 @Transactional 標記 -->
          ????<tx:annotation-driven/>

          ????<!-- 支持 @AspectJ 標記-->
          ????<aop:aspectj-autoproxy/>
          ????
          ????<aop:config proxy-target-class="true">
          ?????? <aop:advisor pointcut="execution(* com.sailing.app.uupms..*.*(..))"
          ?????????????????? advice-ref="txAdvice"/>
          ????</aop:config>
          ????<!-- 基本事務定義,使用transactionManager作事務管理,默認get*方法的事務為readonly,其余方法按默認設(shè)置.
          ????????????默認的設(shè)置請參考Spring文檔事務一章. -->
          ????<tx:advice id="txAdvice">
          ?????? <tx:attributes>
          <!--??????????查詢事務 -->
          ????????????<tx:method name="get*" read-only="true" />
          ?????????? <tx:method name="find*" read-only="true"/>
          ?????????? <tx:method name="load*" read-only="true"/>

          <!--???????????? 新增、修改、刪除事務 -->
          ????????????<tx:method name="save*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="add*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="append*" read-only="false" rollback-for="Exception"/>

          ????????????<tx:method name="update*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="modify*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="edit*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="data*" read-only="false" rollback-for="Exception"/>

          ????????????<tx:method name="remove*" read-only="false" rollback-for="Exception"/>
          ???????????? <tx:method name="delete*" read-only="false" rollback-for="Exception"/>
          ????????????<tx:method name="del*" read-only="false" rollback-for="Exception"/>
          ??????????
          ?????????? <tx:method name="*"/>
          ?????? </tx:attributes>
          ????</tx:advice>
          ????



          </beans>
          其中
          <aop:config proxy-target-class="true">
          ?????? <aop:advisor pointcut="execution(* com.sailing.app.uupms..*.*(..))"
          ?????????????????? advice-ref="txAdvice"/>
          ????</aop:config>
          execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)??其中帶問號的modifiers-pattern?(public/protected) 和 declaring-type-pattern? throws-pattern? 可以不填
          可見execution(* com.sailing.app.uupms..*.*(..))代表com.sailing.app.uupms包下以及子包下的所有類
          以execution(* *..BookManager.save(..))為列子
          第一顆* 代表ret-type-pattern 返回值可任意,
          *..BookManager 代表任意Pacakge里的BookManager類。
          如果寫成com.xyz.service.* 則代表com.xyz.service下的任意類
          com.xyz.service..* com.xyz.service則代表com.xyz.service及其子package下的任意類
          save代表save方法,也可以寫save* 代表saveBook()等方法
          (..) 匹配0個參數(shù)或者多個參數(shù)的,任意類型
          (x,..) 第一個參數(shù)的類型必須是X
          (x,,,s,..) 匹配至少4個參數(shù),第一個參數(shù)必須是x類型,第二個和第三個參數(shù)可以任意,第四個必須是s類型。
          注 意name-pattern千萬不要寫成*..*Manager ,這樣子的話會把所有第三方類庫的Manager比如Spring的PlatformTranstationManager 也加入aop,非常危險。所以最好還是加上項目的package前綴,如org.springside
          回滾在前面的章節(jié)里,概述了如何在你的應用里為類特別是服務層的類指定事務性的基本方法。這一章將描述在一個簡單的聲明式配置中如何你才能控制事務的回滾。
          一個容易的(和被推薦的)方法是在Spring框架的事務架構(gòu)里指出當context的事務里的代碼拋出 Exception 時事務進行回滾。Spring框架的事務基礎(chǔ)架構(gòu)代碼將從調(diào)用的堆棧里捕獲到任何未處理的 Exception,并將標識事務將回滾。
          然而,請注意Spring框架的事務基礎(chǔ)架構(gòu)代碼將默認地 在拋出運行時和unchecked exceptions時才標識事務回滾。 也就是說,當拋出一個 RuntimeException 或其子類例的實例時。(Errors 也一樣 - 默認地 - 標識事務回滾。)從事務方法中拋出的Checked exceptions將 被標識進行事務回滾。
          就是這些默認的設(shè)置;嚴格規(guī)定了哪些 Exception 類型將被標識進行事務回滾。 下面的XML配置片斷里示范了如何配置一個checked,應用程序指定的 Exception 類型來標識事務回滾。
          <tx:advice id="txAdvice" transaction-manager="txManager">
          ??<tx:attributes>
          ???????? <tx:method name="get*" read-only="false" rollback-for="NoProductInStockException"/>
          ???????? <tx:method name="*"/>
          ??</tx:attributes>
          </tx:advice>
          第二方法是在Spring框架的事務架構(gòu)里通過 編程式 方式指出一個事務將被回滾。 雖然這個非常簡單,但是這個方法對于Spring框架的事務架構(gòu)來說,在你的代碼是高入侵的和緊藕合的 下面的代碼片斷里示范了Spring框架管理事務的編程式回滾:
          public void resolvePosition() {
          ????try {
          ????????// some business logic...
          ????} catch (NoProductInStockException ex) {
          ????????// trigger rollback programmatically
          ????????TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
          ????}
          }
          強烈推薦你盡可能地使用聲明式事務回滾方法。 編程式方法的回滾對你來說是可見,如果你需要它你就可以使用,但是使用它就直接違反了在你的應用中使用一個純基于POJO的模型。
          <tx:advice/>有關(guān)的設(shè)置這一節(jié)里將描述通過 <tx:advice/> 標簽來指定不同的事務性設(shè)置。默認的 <tx:advice/> 設(shè)置如下:
          ·???????? 事務傳播設(shè)置是 REQUIRED
          ·???????? 隔離級別是 DEFAULT
          ·???????? 事務是 讀/寫
          ·???????? 事務超時默認是依賴于事務系統(tǒng)的,或者事務超時沒有被支持。
          ·???????? 任何 RuntimeException 將觸發(fā)事務回滾,但是任何 checked Exception 將不觸發(fā)事務回滾
          這些默認的設(shè)置當然也是可以被改變的。 <tx:advice/> 和 <tx:attributes/> 標簽里的 <tx:method/> 各種屬性設(shè)置總結(jié)如下:
          Table 9.1. <tx:method/> 有關(guān)的設(shè)置
          屬性
          是否需要?
          默認值
          描述
          name

          與事務屬性關(guān)聯(lián)的方法名。通配符(*)可以用來指定一批關(guān)聯(lián)到相同的事務屬性的方法。 如:'get*'、'handle*'、'on*Event'等等。
          propagation

          REQUIRED
          事務傳播行為
          isolation

          DEFAULT
          事務隔離級別
          timeout

          -1
          事務超時的時間(以秒為單位)
          read-only

          false
          事務是否只讀?
          rollback-for

          將被觸發(fā)進行回滾的 Exception(s);以逗號分開。 如:'com.foo.MyBusinessException,ServletException'
          no-rollback-for

          被觸發(fā)進行回滾的 Exception(s);以逗號分開。 如:'com.foo.MyBusinessException,ServletException'
          Spring常見錯誤問題1Exceptionin thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.util.ClassUtils.<clinit>(ClassUtils.java:67) at org.springframework.core.io.DefaultResourceLoader.<init>(DefaultResourceLoader.java:52) at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:184) at org.springframework.context.support.AbstractRefreshableApplicationContext.<init>(AbstractRefreshableApplicationContext.java:80) at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:58) at
          需要加上:
          commons-logging.jar log4j-1.2.11.jar
          問題2Exception
          in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [text.xml]; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
          Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
          at java.lang.Class.forName0(Native Method)
          需要加上:
          aspectjweaver.jar
          問題3Exception
          in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logBean' defined in class path resource [text.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
          Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
          需要加上:
          cglib-2.1.3.jar
          問題4
          xception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logBean' defined in class path resource [text.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
          Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/Type
          at net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:180)
          需要加上:
          asm.jar
          轉(zhuǎn)載:
          http://pengchua.javaeye.com/blog/142879
          問題5CGLIB Enhancement failed: com.bowen.domain.Schools
          java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
          at net.sf.cglib.core.ClassEmitter.begin_class(ClassEmitter.java:77)
          at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:173)
          at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
          解決:由于不同版本讓我想到了可能會因為其它三方包是不同版本引起的最新的MyEclipse,所以里面的Hibernate也是最新的3.1(它里面還帶有一個3.0版本的)

          刪除多余的包 Hibernate3.1

          問題6
          org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in resource [/WEB-INF/dataAccessContext-hibernate.xml] of ServletContext: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
          java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
          原因:缺少
          jta.jar
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          問題7

          java.lang.NoClassDefFoundError: org/dom4j/Attribute
          dom4j.jar
          java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException
          ehcache.jar
          java.lang.NoClassDefFoundError: net/sf/cglib/core/KeyFactory
          cglib-full.jar

          posted on 2009-04-29 20:58 tobyxiong 閱讀(1770) 評論(0)  編輯  收藏 所屬分類: java

          <2009年4月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          導航

          統(tǒng)計

          常用鏈接

          留言簿(3)

          隨筆分類(144)

          隨筆檔案(157)

          相冊

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 彝良县| 中超| 新源县| 呼伦贝尔市| 盐源县| 盘山县| 静乐县| 航空| 苗栗县| 凭祥市| 科尔| 平乐县| 安庆市| 曲麻莱县| 鲁甸县| 信阳市| 吴桥县| 东兴市| 海兴县| 新泰市| 芷江| 绥棱县| 临颍县| 镇坪县| 大宁县| 舟山市| 淮滨县| 平果县| 老河口市| 南投县| 酒泉市| 昌吉市| 屏边| 屯门区| 会泽县| 五指山市| 桐柏县| 阿荣旗| 大港区| 大方县| 巴南区|