国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

技術(shù)分享 在Spring中實(shí)現(xiàn)事務(wù)掛起(圖)

2019-11-18 13:00:18
字體:
供稿:網(wǎng)友

  摘要
  
  SPRing Framework是一個流行的java/J2EE應(yīng)用框架,它構(gòu)建于一個輕量級的反向控制(Inversion-of-Control,QoC)模式的容器的基礎(chǔ)之上,以其數(shù)據(jù)訪問和事務(wù)治理能力而著稱。Spring的聲明性事務(wù)劃分適用于任何的POJO(pure old java object或plain ordinary Java object,無格式普通Java對象)目標(biāo)對象,其聲明性事務(wù)如同EJB容器托管事務(wù)(Container-Managed Transaction,CMT)一樣完善。后端事務(wù)治理器的選擇包括簡單的基于JDBC的事務(wù)和完善的J2EE事務(wù)(借助于JTA策略)。
  
  本文具體討論了Spring的事務(wù)治理功能。重點(diǎn)介紹了如何以JTA作為后端事務(wù)策略,使用Spring的針對POJO的聲明性事務(wù)。本文說明了Spring的事務(wù)服務(wù)可以與J2EE服務(wù)器的事務(wù)協(xié)調(diào)程序(如BEA WebLogic Server的事務(wù)協(xié)調(diào)程序)進(jìn)行無縫交互,實(shí)際上已經(jīng)成為EJB CMT的傳統(tǒng)事務(wù)劃分方式的替代方案。
  
  針對POJO的聲明性事務(wù)
  
  為了說明Spring的聲明性事務(wù)劃分方式,讓我們來看看Spring的PetClinic示例應(yīng)用程序的中心服務(wù)外觀(facade)的配置:
  
  <bean id="dataSource"
  class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName">
  <value>java:comp/env/jdbc/petclinic</value>
  </property>
  </bean>
  <bean id="transactionManager"
  class="org.springframework.transaction.jta.JtaTransactionManager"/>
  
  <bean id="clinicTarget"
  class="org.springframework.samples.petclinic.jdbc.JdbcClinic">
  <property name="dataSource"><ref bean="dataSource"/></property>
  </bean>
  
  <bean id="clinic"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager"><ref bean="transactionManager"/></property>
  <property name="target"><ref bean="clinicTarget"/></property>
  <property name="transactionAttributes">
  <props>
  <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
  <prop key="store*">PROPAGATION_REQUIRED</prop>
  </props>
  </property>
  </bean>
  
  它遵從了Spring的標(biāo)準(zhǔn)xmlBean定義格式。它定義了:
  
  一個DataSource引用,指向一個JNDI位置--這將從J2EE服務(wù)器托管的JNDI環(huán)境中獲取指定的DataSource。
  
  一個PlatformTransactionManage實(shí)現(xiàn)--在本例中,該實(shí)現(xiàn)指定Spring的JtaTransactionManager,它委托給J2EE服務(wù)器的事務(wù)協(xié)調(diào)程序。
  
  應(yīng)用程序服務(wù)實(shí)現(xiàn)--這是一個簡單的POJO,它封裝了業(yè)務(wù)和數(shù)據(jù)訪問邏輯。它實(shí)現(xiàn)應(yīng)用程序的Clinic服務(wù)接口。
  
  一個應(yīng)用程序服務(wù)的事務(wù)代理--該代理定義了目標(biāo)服務(wù)的事務(wù)屬性,提供具體的方法命名模式,并創(chuàng)建相應(yīng)的事務(wù)。對于實(shí)際的事務(wù)治理,代理指向PlatformTransactionManager實(shí)現(xiàn)。
  
  注重:Spring還通過通用屬性(Commons Attribute)或者J2SE 5.0的注釋(annotation),支持一種自動代理機(jī)制和對源級(source-level)元數(shù)據(jù)的使用,作為顯示代理定義的替代方案。這些替代方案不在本文的討論范圍之內(nèi);其具體資料請參考Spring說明文檔。
  
  使用的服務(wù)接口和服務(wù)實(shí)現(xiàn)是特定于應(yīng)用程序的,無需了解Spring(具體說是Spring的事務(wù)治理)就可以實(shí)現(xiàn)。純Java對象可以用作目標(biāo)對象,而任何一個純Java接口都可以用作服務(wù)接口。下面是一個Clinic接口的例子:
  
  public interface Clinic {
  Pet loadPet(int id);
  void storePet(Pet pet);
  ...
  }
  下面顯示了該接口的一個簡單實(shí)現(xiàn),假定它使用JDBC來執(zhí)行必要的數(shù)據(jù)訪問。它通過一個bean屬性的setter方法接收J(rèn)DBC DataSource,這直接對應(yīng)上面配置中的dataSource屬性定義。
  
  public class JdbcClinic implements Clinic {
  
  private DataSource dataSource;
  
  public void setDataSource(DataSource dataSource) {
  this.dataSource = dataSource;
  }
  
  public Pet loadPet(int id) {
  try {
  Connection con = this.dataSource.getConnection();
  ...
  }
  catch (SQLException ex) {
  ...
  }
  }
  
  public void storePet(Pet pet) {
  try {
  Connection con = this.dataSource.getConnection();
  ...
  }
  catch (SQLException ex) {
  ...
  }
  }
  
  ...
  }
  正如您所看到的,代碼簡單明了。使用了一個簡單Java對象。事務(wù)治理由事務(wù)代理處理,我們隨后再對其進(jìn)行說明。
  
  注重,PetClinic示例應(yīng)用程序中實(shí)際的基于JDBC的Clinic實(shí)現(xiàn)利用了Spring的JDBC支持類,以免只工作在簡單的JDBC API級別上。但是,Spring的事務(wù)治理還將使用簡單的基于JDBC的實(shí)現(xiàn),比如上面的實(shí)現(xiàn)。
  
  定義事務(wù)代理
  
  除JdbcClinic實(shí)例之外,配置還為其定義了一個事務(wù)代理。假如需要,可以顯式地指定該事務(wù)代理所暴露的實(shí)際接口。默認(rèn)狀態(tài)下,目標(biāo)對象實(shí)現(xiàn)的所有接口都將被暴露--在本例中是應(yīng)用程序的Clinic服務(wù)接口。
  
  從客戶端的角度來看,“clinic”bean只是應(yīng)用程序的Clinic接口的實(shí)現(xiàn)。客戶端不必知道自己正在和事務(wù)代理打交道。這就是接口的力量:目標(biāo)對象的直接引用可以很輕松地由實(shí)現(xiàn)了相同接口的代理取代--在本例中是一個隱式地創(chuàng)建事務(wù)的代理。
  
  對于特定的方法或方法命名模式,代理的具體事務(wù)行為由事務(wù)屬性驅(qū)動,如下面的例子所示:
  
  <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop><prop key="store*">PROPAGATION_REQUIRED</prop>
  
  key屬性確定代理應(yīng)該給哪個方法增加事務(wù)行為。這樣的屬性最重要的部份是傳播行為。有以下選項(xiàng)可供使用:
  
  PROPAGATION_REQUIRED--支持當(dāng)前事務(wù),假如當(dāng)前沒有事務(wù),就新建一個事務(wù)。這是最常見的選擇。
  PROPAGATION_SUPPORTS--支持當(dāng)前事務(wù),假如當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。
  PROPAGATION_MANDATORY--支持當(dāng)前事務(wù),假如當(dāng)前沒有事務(wù),就拋出異常。
  PROPAGATION_REQUIRES_NEW--新建事務(wù),假如當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。
  PROPAGATION_NOT_SUPPORTED--以非事務(wù)方式執(zhí)行操作,假如當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。
  PROPAGATION_NEVER--以非事務(wù)方式執(zhí)行,假如當(dāng)前存在事務(wù),則拋出異常。
  PROPAGATION_NESTED--假如當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。假如當(dāng)前沒有事務(wù),則進(jìn)行與PROPAGATION_REQUIRED類似的操作。
  
  前六個策略類似于EJB CMT:常量名相同,因此,對EJB開發(fā)人員來說,應(yīng)該馬上就感到熟悉。第七個(PROPAGATION_NESTED)是Spring所提供的一個非凡變量。它要求事務(wù)治理器或者使用JDBC 3.0 Savepoint API提供嵌套事務(wù)行為(如Spring的DataSourceTransactionManager),或者通過JTA支持嵌套事務(wù)。
  
  事務(wù)屬性中的readOnly標(biāo)志表示對應(yīng)的事務(wù)應(yīng)該被最優(yōu)化為只讀事務(wù)。這是一個最優(yōu)化提示。在一些情況下,一些事務(wù)策略能夠起到顯著的最優(yōu)化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖“刷新”)。
  
  在事務(wù)屬性中還有定義“timeout”值的選項(xiàng),指定事務(wù)超時為幾秒。在JTA中,這將被簡單地傳遞到J2EE服務(wù)器的事務(wù)協(xié)調(diào)程序,并據(jù)此得到相應(yīng)的解釋。
  
  使用事務(wù)代理
  
  在運(yùn)行時,客戶端將獲取到“clinic”bean的引用,將其轉(zhuǎn)換為Clinic接口,同時在它上面調(diào)用諸如loadPet或storePet之類的操作。這將隱式地使用在目標(biāo)對象之前注冊的“事務(wù)攔截器”檢查Spring的事務(wù)代理;新的事務(wù)將被創(chuàng)建,然后調(diào)用將被委派給JdbcClinic目標(biāo)方法。
  
  圖1說明了一個具有“advisor鏈”和終端目標(biāo)的AOP代理的底層概念。其中,唯一的advisor就是將事務(wù)行為包裝到目標(biāo)方法的事務(wù)攔截器。這是在Spring的聲明性事務(wù)功能的幫助下產(chǎn)生的基于代理的AOP(面向方面編程)。
  
 技術(shù)分享 在Spring中實(shí)現(xiàn)事務(wù)掛起(圖)
  圖1. 具有“advisor鏈”和終端目標(biāo)的AOP代理

  
  例如,PetClinic web應(yīng)用程序中的web層組件能夠執(zhí)行ServletContext查詢操作來獲取對Spring WebapplicationContext的引用,然后獲得那里托管的“Clinic”bean:
  
  WebApplicationContext ctx =
  WebApplicationContexUtils.getWebApplicationContext(servletContext);
  Clinic clinic = (Clinic) ctx.getBean("clinic);
  
  Pet pet = new Pet();
  pet.setName("my new cat");
  
  clinic.storePet(pet);  在storePet()調(diào)用的開始,Spring的事務(wù)代理將隱式地創(chuàng)建一個事務(wù)。在storePet()調(diào)用返回時,將提交或回滾事務(wù)。默認(rèn)情況下,任何RuntimeException或Error的拋出均會導(dǎo)致回滾??梢灾付ê螘r提交和何時回滾的實(shí)際規(guī)則:Spring的事務(wù)屬性支持一個稱為“回滾規(guī)則”的概念。
  
  例如,我們可以引入一個檢查性的PetClinicException,并告訴事務(wù)代理,在拋出該異常時執(zhí)行進(jìn)行回滾。
  
  <prop key="load*">PROPAGATION_REQUIRED,readOnly,-PetClinicException</prop>
  <

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 青海省| 庆云县| 阜新市| 贵德县| 昌乐县| 保康县| 永丰县| 平利县| 杭州市| 内江市| 合水县| 太和县| 遂平县| 泸水县| 哈巴河县| 堆龙德庆县| 买车| 南汇区| 克山县| 西乌珠穆沁旗| 嘉黎县| 宜春市| 天柱县| 阳新县| 东莞市| 讷河市| 静安区| 昭平县| 府谷县| 湖口县| 东乌珠穆沁旗| 潮州市| 北宁市| 吉安市| 晋宁县| 江永县| 井陉县| 涡阳县| 永兴县| 公安县| 宁德市|