少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
          讓Spring架構減化事務配置
          注:原創文章,本文曾發表于it168
          Spring顛覆了以前的編程模式,引入了IOC等全新的概念,廣受大家的喜愛。目前大多數j2ee項目都已經采用Spring框架。Spring最大的問題是太多的配置文件,使得你不僅需要維護程序代碼,還需要額外去維護相關的配置文件。最典型的就是事務配置(注:這里的“事務配置”都指“聲明式事務配置”),在Spring中進行事務配置除了定義對象自身的bean外,還需要定義一個進行事務代理的bean.如果你有n個類需要引入事務,那么你就必須定義2n個bean。維護這些bean的代價是十分昂貴的,所以必須要對事務配置進行減化。如果你是基于Spring進行架構設計,那么作為一個好的架構設計師,應該把一些公共的方面進行簡化,讓項目的開發人員只關心項目的業務邏輯,而不要花費太多的精力去關心業務邏輯之外的太多東西。所以作為一個好的架構就應該把事務管理進行簡化,讓程序員花在編程之外的工作最小化。
          1. Spring聲明式事務配置的幾種方法
          在Spring中進行事務控制首先要選擇適當的事務管理器,其次為程序選擇劃分事務的策略。如果只有單個事務性資源,可以從“單一資源”的PlatformTransactionManger實現當中選擇一個,這些實現有:DataSourceTransactionManager,HibernateTransactionManager, JdoTransactionManager,PersistenceBrokerTransactionManager和JmsTransactionManager。根據你所采用的數據庫持久化技術選擇。如果你的項目運行于支持JTA的服務器,那么將選擇JtaTransactionManger,將會支持多資源事務。
          下表將為你選擇適當的事務管理器提供參考。
          技術 事務管理器 內建的事務支持
          JDBC DataSurceTransactionManagerJtaTransactionManager JdbcTemplate和org.springframework.jdbc.object包中的所有類
          IBATIS DataSourceTransactionManagerJtaTransactionManager SqlMapClientTemplate和SqlClientTemplate
          Hibernate HibernateTransactionManagerJtaTransactionManager HibernateTemplate和HibernateInterceptor
          JDO JdoTransactionManagerJtaTransactionManager JdoTemplate和JdoInterceptor
          ApacheOJB PersistenceBrokerTransactionManagerJtaTransactionManager PersistenceBrokerTemplate
          JMS JmsTransactionManager JmsTemplate

          在劃分事務時,我們需要進行事務定義,也就是配置事務的屬性。事務的屬性有傳播行業,隔離級別,超時值及只讀標志。TransactionAttribute接口指定哪些異常將導致一個回滾,哪些應該一次性提交。

          (1) 使用ProxyFactoryBean 和TransactionInterceptor

          <!--定義本地數據源-->

          <bean id="dataSource" name="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>


          <!-- !定義單個jdbc數據源的事務管理器-->
          <bean id="transactionManager"               class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"/>
          </bean>

             <!—定義攔截器-->
          <bean id="transactionInterceptor"
                class="org.springframework.transaction.interceptor.TransactionInterceptor">
              <property name="transactionManager">
              <ref bean="transactionManager"/>
              </property>
                  <property name="transactionAttributes">
                      <props>
                          <prop key="insert*">PROPAGATION_REQUIRED</prop>
                          <prop key="update*">PROPAGATION_REQUIRED</prop>
                          <prop key="save*">PROPAGATION_REQUIRED</prop>
                          <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
                      </props>
                  </property>
              </bean>

          <!—定義業務對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
                 class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
          <property name="userInfoDAO"
              ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
          </property>
          </bean>

          <!—定義業務對象的事務代理對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService" class="org.springframeword.aop.framework.ProxyFacgtoryBean">
          <property name="target"
              ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
          </property>
          <property name="interceptorNames">
              <value>transactionInterceptor</value>
          </property>
          </bean>

          通過ProxyFacgtoryBean和TransactionInterceptor組合使用,可以對事務進行更多的控制。所有需要事務控制的對象可以共享一個transactionInterceptor的事務屬性。

          (2) 使用TransactionProxyFactoryBean

          <!—定義業務對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
                 class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
          <property name="userInfoDAO"
              ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
          </property>
          </bean>

              <!—定義業務對象的事務代理對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
                    abstract="true">
                  <property name="transactionManager">
                      <ref bean="transactionManager"/>
                  </property>
          <property name="target"
                    ref="com.prs.application.ehld.sample.biz.service.sampleService.target" />
                  <property name="transactionAttributes">
                      <props>
                          <prop key="insert*">PROPAGATION_REQUIRED</prop>
                          <prop key="update*">PROPAGATION_REQUIRED</prop>
                          <prop key="save*">PROPAGATION_REQUIRED</prop>
                          <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
                      </props>
                  </property>
              </bean>

          使用TransactionProxyFactoryBean需要為每一個代理對象都去定義自己的事務屬性。

          (3) 使用TransactionProxyFactoryBean及abstract屬性來簡化配置
          這種方工也是目前使用得最多的一種聲明式事務配置方法


          <!--事務控制代理抽象定義 -->
          <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
                  abstract="true">
                  <property name="transactionManager">
                      <ref bean="transactionManager"/>
                  </property>
                  <property name="transactionAttributes">
                      <props>
                          <prop key="insert*">PROPAGATION_REQUIRED</prop>
                          <prop key="update*">PROPAGATION_REQUIRED</prop>
                          <prop key="save*">PROPAGATION_REQUIRED</prop>
                          <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
                      </props>
                  </property>
              </bean>

          <!—定義業務對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
                 class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
          <property name="userInfoDAO"
              ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
          </property>
          </bean>

          <!—定義業務對象的事務代理對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService" parent="baseTransactionProxy">
          <property name="target"
              ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
          </property>
          </bean>

          使用abstract屬性,可以讓代理對象可以共享一個定義好的事務屬性,使配置簡化。

          (4)使用BeanNameAutoProxyCreator
              <!—定義攔截器-->
          <bean id="transactionInterceptor"
                class="org.springframework.transaction.interceptor.TransactionInterceptor">
              <property name="transactionManager">
              <ref bean="transactionManager"/>
              </property>
                  <property name="transactionAttributes">
                      <props>
                          <prop key="insert*">PROPAGATION_REQUIRED</prop>
                          <prop key="update*">PROPAGATION_REQUIRED</prop>
                          <prop key="save*">PROPAGATION_REQUIRED</prop>
                          <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                          <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
                      </props>
                  </property>
              </bean>


          <!—定義bean別名自動代理創建器-->
          <bean id="autoProxyCreator"
             class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
              <property name="interceptorNames">
                 <value>transactionInterceptor</value>
              </property>
              <property name="beanNames">
              <list>
              <idref local="com.prs.application.ehld.sample.biz.service.sampleService"/>
              </list>
              </property>
          </bean>

          <!—定義業務對象-->
          <bean id="com.prs.application.ehld.sample.biz.service.sampleService"
                 class="com.prs.application.ehld.sample.biz.service.impl.SampleServiceImpl">
          <property name="userInfoDAO"
              ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
          </property>
          </bean>

          使用BeanNameAutoProxyCreator可以由框架來提供適當的代理,由一個transactionInterceptor統一定義事務屬性,只需要把需要事務控制的bean加到beannames的列表。
            對于需要大量聲明式事務的bean,BeanNameAutoProxyCreator是十分方便的。減少了代理bean的定義,還可以靈活的決定一個bean是否進行事務控制。


          上面四種方法是在Spring中常見的聲明式事務配置方法,其中使用TransactionProxyFactoryBean及abstract屬性進行配置是最常見的簡化方法。



          http://www.iteye.com/topic/72435












          posted on 2012-03-04 17:48 abin 閱讀(541) 評論(0)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 南乐县| 溧水县| 轮台县| 铁力市| 乳山市| 都匀市| 布尔津县| 息烽县| 化德县| 北宁市| 贺州市| 玉门市| 宝山区| 新干县| 永丰县| 建阳市| 安达市| 定兴县| 新疆| 资溪县| 姜堰市| 红桥区| 巍山| 汉中市| 郁南县| 福鼎市| 伊宁县| 大冶市| 凌海市| 泸定县| 鄂托克旗| 永昌县| 瑞安市| 阳山县| 科尔| 加查县| 久治县| 东山县| 荆门市| 通江县| 黄平县|