熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

在Spring中配置Hibernate事務(圖)

2013-11-23 20:26:13  來源: Java開源技術 

  這篇文章主要探討怎麼用Spring來裝配組件及其事務管理在JEE工程裡連接到一個簡單的數據庫並不是什麼難題但是如果要綜合組裝企業類的組件就變得復雜了一個簡單的組件有一個或多個數據庫支撐所以我們說到整合兩個或多個的組件時我們希望能夠維持跨組件的許多數據庫的運作的原子性
  
  JEE提供了這些組件的容器可以保證處理的原子性和獨立性在沒有JEE的情況下我們可以用SpringSpring基於IoC模式(即反轉模式)不僅可以配置組件服務還可以配置相應的方法為了更好的實現本文的目的我們使用Hibernate來做相應的後台開發
  
  裝配組件事務
  
  假設在組件庫裡我們已經有一個審核組件(audit component)裡面有可以被客戶端調用的方法接著當我們想要構建一個處理訂單的體系我們發現設計需要的OrderListManager組件服務同樣需要審核組件服務OrderListManager創建和管理訂單每一個服務都含有自己的事務屬性當這時調用審核組件就可以把OrderListManager的處理內容傳給它也許將來新的業務服務(business service)同樣需要審核組件那這時它調用的事務內容已經不一樣了在網絡上的結果就是雖然審核的功能保持不變但是可以和別的事件功能組合在一起用這些方法屬性來提供不同的運行時的處理參數
  
  在圖中有兩個分開的調用流程在流程如果客戶端含有一個TX內容OrderListManager 要由一個新的TX開始或者參與其中取決於客戶端在不在TX裡以及OrderListManager方法指定的TX屬性這在它調用AuditManager方法的時候仍然適用
  
 

  
裝配組件事務

  
  EJB體系通過裝配者聲明正確的事務屬性來獲得這種適應性我們不是在探討是否聲明事務管理因為這會使運行時的事務參數代碼發生改變幾乎所有的JEE工程提供了分布的事務管理來配合提交協議例如X/Open XA specification
  
  現在的問題是我們能不能不用EJB來獲得相同的功能?Spring是其中一種解決方案來看一下Spring如何處理這樣的問題
  
  用Spring來管理事務
  
  我們將看到的是一個輕量級的事務機制實際上它可以管理組件層的事務集成Spring就是如此它的優點是我們可以不用捆綁在JEE的服務例如JNDI數據庫最棒的是如果我們想把這個事務機制與已經存在的JEE框架組合在一起沒有任何問題就好像我們找到了槓桿中完美的支撐點一樣
  
  Spring的另一個機制是使用了AOP框架這個框架使用了一個可以使用AOP的Spring bean factory在Spring特定的配置文件applicationContextxml裡通過特定的組件層的事件來指定
  
  <beans><! other code goes here >
  <bean id=orderListManager    class=orgspringframeworktransaction interceptorTransactionProxyFactoryBean><property name=transactionManager>
  <ref local=transactionManager/></property><property name=target>
  <ref local=orderListManagerTarget/></property><property name=transactionAttributes>
  <props><prop key=getAllOrderList>            PROPAGATION_REQUIRED        </prop>
  <prop key=getOrderList>            PROPAGATION_REQUIRED        </prop>        <prop key=createOrderList>            PROPAGATION_REQUIRED        </prop>
  <prop key=addLineItem>          PROPAGATION_REQUIRED          comexampleexceptionFacadeException        </prop>        <prop key=getAllLineItems>            PROPAGATION_REQUIREDreadOnly        </prop>
  <prop key=queryNumberOfLineItems>            PROPAGATION_REQUIREDreadOnly        </prop>
  </props></property></bean></beans>
  
  一旦我們在服務層指定了事務屬性它們就被一個繼承orgspringframeworktransactionPlatformTransactionManager 接口的類截獲 這個接口如下:
  
  public interface PlatformTransactionManager{    TransactionStatus getTransaction        (TransactionDefinition definition);
  void commit(TransactionStatus status);
  void rollback(TransactionStatus status);}
  
  Hibernate事務管理
  
  一旦我們決定了使用Hibernate作為ORM工具我們下一步要做的就是用Hibernate特定的事務管理實例來配置
  
  <beans><! other code goes here ><bean id=transactionManager    class=orgspringframeworkormhibernate        HibernateTransactionManager>
  <property name=sessionFactory>
  <ref local=sessionFactory/>
  </property></bean></beans>
  我們來看看什麼是裝配組件事務你也許注意到了那個OrderListManager 特有的TX屬性那個服務層的組件我們的工程的主要的東西在表的BDOM裡:
  
 educitycn/img_///gif >

  
業務領域對象模型 (BDOM)

  
  為了用實例說明我們來列出工程裡的非功能需求(NFR)
  
  事務在數據庫appfuse裡保存
  審核時要登入到另一個數據庫appfuse出於安全的考慮數據庫有防火牆保護
  事務組件可以重用
  所有訪問事件必須經過在事務服務層的審核
  
  出於以上的考慮我們決定了OrderListManager 服務將委托任何審核記錄來調用已有的AuditManager 組件這產生了表這樣更細致的結構
  
 educitycn/img_///gif >

  
組件服務結構設計

  
  值得注意的是由於我們的NFR我們要映射OrderListManager相關的事物到appfuse 數據庫裡去而審核相關的到appfuse這樣任何審核的時候 OrderListManager 組件都會調用AuditManager 組件我們認為OrderListManager 組件裡的所有方法都要執行 因為我們通過服務來創建次序和具體項目那麼AuditManager 組件裡的服務呢? 因為它做的是審核的動作我們關心的是為系統裡所有的事務記錄審核情況這樣的需求是即使事務事件失敗了我們也要記錄登錄的審核情況AuditManager 組件同樣要有自己的事件因為它同樣與自己的數據庫有關聯如下所示
  
  <beans><!—其他代碼在這裡><bean id=auditManager    class=orgspringframeworktransaction interceptorTransactionProxyFactoryBean>    <property name=transactionManager>        <ref local=transactionManager/>    </property>
  <property name=target>        <ref local=auditManagerTarget/>    </property>
  <property name=transactionAttributes>
  <props>
  <prop key=log>
  PROPAGATION_REQUIRES_NEW
  </prop>
  </props>
  </property></bean></beans>
  
  我們現在把注意力放到這兩個事務createOrderList 和 addLineItem中來作為我們的試驗同時注意我們並沒有要求最好的設計——你可能注意到了 addLineItem 方法拋出了 FacadeException 而 createOrderList 沒有在產品設計中你也許希望每一個方法都處理異常
  public class OrderListManagerImpl
  implements OrderListManager{private AuditManager auditManager;public Long createOrderList (OrderList orderList){
  Long orderId = orderListDAO        createOrderList(orderList);
  auditManagerlog(new AuditObject
  (ORDER + orderId CREATE));
  return orderId;}public void addLineItem (Long orderId LineItem lineItem)
  throws FacadeException{
  Long lineItemId = orderListDAO
  addLineItem(orderId lineItem);
  auditManagerlog(new AuditObject
  (LINE_ITEM + lineItemId CREATE));
  int numberOfLineItems = orderListDAO
  queryNumberOfLineItems(orderId);
  if(numberOfLineItems > ){
  log(Added LineItem + lineItemId +
   to Order + orderId + ;
  But rolling back *** !);
  throw new FacadeException(Make a new
  Order for this line item);
  }
  else{
  log(Added LineItem + lineItemId +
   to Order + orderId + );
  }}//其他代碼在這裡}
  
  要創建一個這個試驗的異常我們已經介紹了其他事務規則規定一個特定的次序不能在同一行裡包含兩個項目我們應該注意到createOrderList 和 addLineItem調用了auditManagerlog() 方法你應該也注意到了上面方法中的事務屬性
  <bean id=orderListManager
  class=orgspringframeworktransaction
  interceptorTransactionProxyFactoryBean>
  <pro
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28501.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.