1. 程式人生 > >面試題整理--開發中實現spring的事務有5種方式

面試題整理--開發中實現spring的事務有5種方式

Spring+Hibernate的實質:
就是把Hibernate用到的資料來源Datasource,Hibernate的SessionFactory例項,事務管理器HibernateTransactionManager,都交給Spring管理。

那麼再沒整合之前Hibernate是如何實現事務管理的呢?
通過ServletFilter實現資料庫事務的管理,這樣就避免了在資料庫操作中每次都要進行資料庫事務處理。

一.事務的4個特性:
原子性:一個事務中所有對資料庫的操作是一個不可分割的操作序列,要麼全做,要麼全部做。
一致性:資料不會因為事務的執行而遭到破壞。
隔離性:一個事務的執行,不受其他事務(程序)的干擾。既併發執行的個事務之間互不干擾。
永續性:一個事務一旦提交,它對資料庫的改變將是永久的。

二.事務的實現方式:
實現方式共有兩種:編碼方式;宣告式事務管理方式。

基於AOP技術實現的宣告式事務管理,實質就是:在方法執行前後進行攔截,然後在目標方法開始之前建立並加入事務,執行完目標方法後根據執行情況提交或回滾事務。

宣告式事務管理又有兩種方式:基於XML配置檔案的方式;另一個是在業務方法上進行@Transactional註解,將事務規則應用到業務邏輯中。

三.建立事務的時機:

是否需要建立事務,是由事務傳播行為控制的。讀資料不需要或只為其指定只讀事務,而資料的插入,修改,刪除就需要事務管理了。

Spring
配置檔案中關於事務配置總是由三個組成部分,分別是DataSourceTransactionManager和代理機制這三部分,無論哪種配置方式,一般變化的只是代理機制這部分。

    DataSourceTransactionManager這兩部分只是會根據資料訪問方式有所變化,比如使用Hibernate進行資料訪問時,DataSource實際為SessionFactoryTransactionManager的實現為HibernateTransactionManager

具體如下圖:


根據代理機制的不同,總結了五種Spring事務的配置方式,配置檔案如下:

第一種方式:每個Bean

都有一個代理

  1.     <beanid="sessionFactory"
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  3.         <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
  4.         <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
  5.     </
    bean>
  6.     <!-- 定義事務管理器(宣告式的事務) -->
  7.     <beanid="transactionManager"
  8.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  9.         <propertyname="sessionFactory"ref="sessionFactory"/>
  10.     </bean>
  11.     <!-- 配置DAO -->
  12.     <beanid="userDaoTarget"class="com.bluesky.spring.dao.UserDaoImpl">
  13.         <propertyname="sessionFactory"ref="sessionFactory"/>
  14.     </bean>
  15.     <beanid="userDao"
  16.         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  17.            <!-- 配置事務管理器 -->
  18.            <propertyname="transactionManager"ref="transactionManager"/>
  19.         <propertyname="target"ref="userDaoTarget"/>
  20.          <propertyname="proxyInterfaces"value="com.bluesky.spring.dao.GeneratorDao"/>
  21.         <!-- 配置事務屬性 -->
  22.         <propertyname="transactionAttributes">
  23.             <props>
  24.                 <propkey="*">PROPAGATION_REQUIRED</prop>
  25.             </props>
  26.         </property>
  27.     </bean>
  28. </beans>

第二種方式:所有Bean共享一個代理基類

  1.     <beanid="sessionFactory"
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  3.         <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
  4.         <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
  5.     </bean>
  6.     <!-- 定義事務管理器(宣告式的事務) -->
  7.     <beanid="transactionManager"
  8.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  9.         <propertyname="sessionFactory"ref="sessionFactory"/>
  10.     </bean>
  11.     <beanid="transactionBase"
  12.             class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
  13.             lazy-init="true"abstract="true">
  14.         <!-- 配置事務管理器 -->
  15.         <propertyname="transactionManager"ref="transactionManager"/>
  16.         <!-- 配置事務屬性 -->
  17.         <propertyname="transactionAttributes">
  18.             <props>
  19.                 <propkey="*">PROPAGATION_REQUIRED</prop>
  20.             </props>
  21.         </property>
  22.     </bean>
  23.     <!-- 配置DAO -->
  24.     <beanid="userDaoTarget"class="com.bluesky.spring.dao.UserDaoImpl">
  25.         <propertyname="sessionFactory"ref="sessionFactory"/>
  26.     </bean>
  27.     <beanid="userDao"parent="transactionBase">
  28.         <propertyname="target"ref="userDaoTarget"/>
  29.     </bean>
  30. </beans>

第三種方式:使用攔截器

  1.     <beanid="sessionFactory"
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  3.         <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
  4.         <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
  5.     </bean>
  6.     <!-- 定義事務管理器(宣告式的事務) -->
  7.     <beanid="transactionManager"
  8.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  9.         <propertyname="sessionFactory"ref="sessionFactory"/>
  10.     </bean>
  11.     <beanid="transactionInterceptor"
  12.         class="org.springframework.transaction.interceptor.TransactionInterceptor">
  13.         <propertyname="transactionManager"ref="transactionManager"/>
  14.         <!-- 配置事務屬性 -->
  15.         <propertyname="transactionAttributes">
  16.             <props>
  17.                 <propkey="*">PROPAGATION_REQUIRED</prop>
  18.             </props>
  19.         </property>
  20.     </bean>
  21.     <beanclass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  22.         <propertyname="beanNames">
  23.             <list>
  24.                 <value>*Dao</value>
  25.             </list>
  26.         </property>
  27.         <propertyname="interceptorNames">
  28.             <list>
  29.                 <value>transactionInterceptor</value>
  30.             </list>
  31.         </property>
  32.     </bean>
  33.     <!-- 配置DAO -->
  34.     <beanid="userDao"class="com.bluesky.spring.dao.UserDaoImpl">
  35.         <propertyname="sessionFactory"ref="sessionFactory"/>
  36.     </bean>
  37. </beans>


第四種方式:使用tx標籤配置的攔截器

  1.     <beanid="sessionFactory"
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  3.         <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
  4.         <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
  5.     </bean>
  6.     <!-- 定義事務管理器(宣告式的事務) -->
  7.     <beanid="transactionManager"
  8.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  9.         <propertyname="sessionFactory"ref="sessionFactory"/>
  10.     </bean>
  11.     <tx:adviceid="txAdvice"transaction-manager="transactionManager">
  12.         <tx:attributes>
  13.             <tx:methodname="*"propagation="REQUIRED"/>
  14.         </tx:attributes>
  15.     </tx:advice>
  16.     <aop:config>
  17.         <aop:pointcutid="interceptorPointCuts"
  18.             expression="execution(* com.bluesky.spring.dao.*.*(..))"/>
  19.         <aop:advisoradvice-ref="txAdvice"
  20.             pointcut-ref="interceptorPointCuts"/>
  21.     </aop:config>
  22. </beans>

第五種方式:全注

  1.     <tx:annotation-driventransaction-manager="transactionManager"/>
  2.     <beanid="sessionFactory"
  3.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  4.         <propertyname="configLocation"value="classpath:hibernate.cfg.xml"/>
  5.         <propertyname="configurationClass"value="org.hibernate.cfg.AnnotationConfiguration"/>
  6.     </bean>
  7.     <!-- 定義事務管理器(宣告式的事務) -->
  8.     <beanid="transactionManager"
  9.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  10.         <propertyname="sessionFactory"ref="sessionFactory"/>
  11.     </bean>
  12. </beans>

此時在Service類上需加上@Transactional註解