麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

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

2019-11-18 13:00:18
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美一级美国一级 | 国产jjizz一区二区三区视频 | 精品日韩欧美 | av免费在线观| 国产精品剧情一区二区在线观看 | 麻豆国产网站 | 男女亲热网站 | 久久精品国产亚洲7777 | 在线91视频| 久久久久久久亚洲视频 | 欧美日韩手机在线观看 | free korean xxxxhd | 国产小视频在线观看 | 黄色男女视频 | 视频一区二区精品 | 国产一区国产二区在线观看 | 精品成人av一区二区三区 | 久久精品国产99国产精品亚洲 | 在线播放污 | 日韩欧美电影一区二区三区 | 在线视频 欧美日韩 | 国产二三区 | 日韩欧美色综合 | 在线看91| 久久影院一区二区三区 | 91短视频网页版 | 成人做爽爽爽爽免费国产软件 | 2021免费日韩视频网 | 最新久久免费视频 | 国产精品麻豆91 | 嫩草影院在线观看网站成人 | 羞羞网站入口 | 欧美日本日韩 | 九九热在线精品视频 | 亚洲一区二区 | 久草在线综合 | 中文字幕欧美一区二区三区 | 特级黄aaaaaaaaa毛片 | 91经典视频| 视频一区二区国产 | 欧美成年人视频在线观看 |