Spring 註解事務,聲明事務共存的情況下,先後順序

首先先看配置文件:

  1. <!-- hibernate -->  
  2.     <bean id="sessionFactory"  
  3.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  4.         <property name="dataSource" ref="dataSource" />  
  5.         <property name="hibernateProperties">  
  6.             <props>  
  7.                 <prop key="hibernate.hbm2ddl.auto">update</prop>  
  8.                 <prop key="hibernate.show_sql">true</prop>  
  9.                 <prop key="hibernate.format_sql">true</prop>  
  10.                 <prop key="connection.autoReconnect">true</prop>  
  11.                 <prop key="connection.autoReconnectForPools">true</prop>  
  12.                 <prop key="connection.is-connection-validation-required">true</prop>  
  13.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
  14.             </props>  
  15.         </property>  
  16.         <property name="mappingDirectoryLocations">  
  17.             <list>  
  18.                 <value>classpath*:*oddtech/bean</value>  
  19.             </list>  
  20.         </property>  
  21.     </bean>  
  22.   
  23.     <!-- 事務管理 -->  
  24.     <bean id="txManager"  
  25.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  26.         <property name="sessionFactory" ref="sessionFactory" />  
  27.     </bean>  
  28.     <!-- 註解式事務的支持 -->  
  29.     <tx:annotation-driven transaction-manager="txManager"  order="0"/>  
  30.     <!-- 服務事務註冊切面 -->  
  31.     <aop:config >  
  32.         <aop:pointcut expression="execution(* oddtech.service.impl.*.*(..))"  
  33.             id="txPoint"  />  
  34.         <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"  order="1"/>  
  35.     </aop:config>  
  36.   
  37.       
  38.   
  39.   
  40.     <tx:advice transaction-manager="txManager" id="txAdvice">  
  41.         <tx:attributes >  
  42.             <tx:method name="find*" propagation="REQUIRED" read-only="true"   
  43.                 rollback-for="Exception" />  
  44.             <tx:method name="select*" propagation="REQUIRED" read-only="true"  
  45.                 rollback-for="Exception" />  
  46.             <tx:method name="insert*" propagation="REQUIRED"    
  47.                 rollback-for="Exception" />  
  48.             <tx:method name="delete*" propagation="REQUIRED"  
  49.                 rollback-for="Exception" />  
  50.             <tx:method name="update*" propagation="REQUIRED"   
  51.                 rollback-for="Exception" />  
  52.             <tx:method name="modify*" propagation="REQUIRED"  
  53.                 rollback-for="Exception" />  
  54.             <tx:method name="*" read-only="true"  
  55.                 rollback-for="Exception" />  
  56.         </tx:attributes>  
  57.     </tx:advice>  

當在oddtech.service.impl包下某個類(Test)某個方法(insert)使用了@Transactional,相當於在執行new Test().insert() 方法執行2次AOP切面。那麼我們需要通過order 屬性去定義AOP切面的先後執行順序。 order越小,在AOP的chain 中越靠前,越先執行。(chain模式)

如果不定義order,默認優先級最高


所以 我們需要在<tx:annotation-driven transaction-manager="txManager"  order="0"/>中加入order屬性爲0,<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"  order="1"/>加入order 屬性爲1.那麼他們兩個的執行順序如下:

。這樣就屬於事務嵌套。

那麼我們再看上邊說的例子:當在oddtech.service.impl包下某個類(Test)某個方法(insert)使用了@Transactional,那麼我們想讓insert 方法只讀,read-only=true,那麼我們需要這樣去定義:@Transactional(readOnly = true,propagation=Propagation.REQUIRED),爲什麼呢?

在聲明事務中,我們對insert 的事務傳播級別定義爲:REQUIRED,關於事務傳播級別,請參照http://blog.csdn.net/feng27156/article/details/8534609,那麼在註解事務中我們定義REQUIRED 的事務。聲明事務在使用註解定義的事務級別。

除非在特殊的情況下,註解事務不要和聲明事務有衝突。聲明事務定義的是統一的規則,如果你想讓某一個方法有特殊的事務傳播機制的話,那麼不要和統一的規則有衝突。

<tx:method name="*" read-only="true" rollback-for="Exception" />

按照規則,定義一個test方法,加入:@Transactional定義。則test 方法爲read-only=false,propagation=REQUIRED。這是默認的。統一規則<tx:method name="*" read-only="true" rollback-for="Exception" />不會對test方法的註解事務衝突。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章