spring2.0 事務配置
![]() ![]() 一般來說,選擇PlatformTransactionManager實現時需要知道當前的工作環境,如JDBC、JTA、Hibernate等。下面的例子來自Spring示例應用—— 我們必須先定義一個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框架的 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> 聲明式事務管理 Spring的聲明式事務管理是通過Spring AOP實現的,因為事務方面的代碼與Spring綁定并以一種樣板式風格使用,不過盡管如此,你一般并不需要理解AOP概念就可以有效地使用Spirng的聲明式事務管理。 從考慮EJB CMT和Spring聲明式事務管理的相似以及不同之處出發是很有益的。它們的基本方法是相似的:都可以指定事務管理到單獨的方法;如果需要可以在事務上下文調用 setRollbackOnly() 回滾規則的概念比較重要:它使我們能夠指定什么樣的異常(和throwable)將導致自動回滾。我們在配置文件中聲明式地指定,無須在Java代碼中。同時,我們仍舊可以通過調用 TransactionStatus 的 setRollbackOnly() 方法編程式地回滾當前事務。通常,我們定義一條規則,聲明 MyApplicationException 對EJB來說,默認的行為是EJB容器在遇到 列子: 清單1: <!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 <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,其余方法按默認設置. ????????????默認的設置請參考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(* *..BookManager.save(..))為列子 第一顆* 代表ret-type-pattern 返回值可任意, 如果寫成com.xyz.service.* 則代表com.xyz.service下的任意類 com.xyz.service..* com.xyz.service則代表com.xyz.service及其子package下的任意類 save代表save方法,也可以寫save* 代表saveBook()等方法 (..) 匹配0個參數或者多個參數的,任意類型 (x,..) 第一個參數的類型必須是 (x,,,s,..) 匹配至少4個參數,第一個參數必須是x類型,第二個和第三個參數可以任意,第四個必須是s類型。 注 意name-pattern千萬不要寫成*..*Manager ,這樣子的話會把所有第三方類庫的Manager比如Spring的PlatformTranstationManager 也加入aop,非常危險。所以最好還是加上項目的package前綴,如org.springside 一個容易的(和被推薦的)方法是在Spring框架的事務架構里指出當context的事務里的代碼拋出 Exception 時事務進行回滾。Spring框架的事務基礎架構代碼將從調用的堆棧里捕獲到任何未處理的 Exception 然而,請注意Spring框架的事務基礎架構代碼將默認地 就是這些默認的設置;嚴格規定了哪些 Exception 類型將被標識進行事務回滾。 下面的XML配置片斷里示范了如何配置一個checked,應用程序指定的 Exception <tx:advice id="txAdvice" transaction-manager="txManager"> ??<tx:attributes> ???????? <tx:method name="get*" read-only="false" ???????? <tx:method name="*"/> ??</tx:attributes> </tx:advice> 第二方法是在Spring框架的事務架構里通過 public void resolvePosition() { ????try { ???????? ????} catch (NoProductInStockException ex) { ???????? ????????TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); ????} } 強烈推薦你盡可能地使用聲明式事務回滾方法。 編程式方法的回滾對你來說是可見,如果你需要它你就可以使用,但是使用它就直接違反了在你的應用中使用一個純基于POJO的模型。 這些默認的設置當然也是可以被改變的。 <tx:advice/> 和 <tx:attributes/> 標簽里的 <tx:method/> 是 與事務屬性關聯的方法名。通配符(*)可以用來指定一批關聯到相同的事務屬性的方法。 如:'get*'、'handle*'、'on*Event'等等。 propagation 不 REQUIRED 事務傳播行為 isolation 不 DEFAULT 事務隔離級別 timeout 不 -1 事務超時的時間(以秒為單位) read-only 不 false 事務是否只讀? rollback-for 不 將被觸發進行回滾的 Exception(s);以逗號分開。 如:'com.foo.MyBusinessException,ServletException' no-rollback-for 不 Spring常見錯誤問題1 需要加上: 問題2 Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException at java.lang.Class.forName0(Native Method) 需要加上: 問題3 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. 需要加上: 問題4 Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/Type at net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:180) 需要加上: 轉載: 問題5 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 刪除多余的包 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 原因:缺少 ~~~~~~~~~~~~~~~~~ 問題7 java.lang.NoClassDefFoundError: org/dom4j/Attribute 缺 java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException 缺 java.lang.NoClassDefFoundError: net/sf/cglib/core/KeyFactory 缺cglib-full.jar |
posted on 2009-04-29 20:58 tobyxiong 閱讀(1770) 評論(0) 編輯 收藏 所屬分類: java