`

Struts2+EJB2+Spring2+Ibatis分布式事务参考

阅读更多

近日闲来无事,结合平时项目开发使用EJB2.x过程中带来的种种不便,决定结合Spring深入总结和研究下EJB开发和调用方面技术,主要包括三个方面:

 

1、事务控制

在Struts2+EJB2+Spring2+Ibatis的技术架构中,有三个地方可以进行事务控制

1)通过EJB2进行全局事务控制,EJB的事务控制分为两种:容器管理事务和Bean管理事务

使用EJB容器管理事务默认启用的是JTA事务,且是基于EJB方法的事务控制,要求在EJB方法包含完成一个业务且需要进行事务控制的各种操作,下边给出一个完整实例。

示例1(将事务完全交由ejb容器进行管理):

Spring的applicationContext.xml文件配置:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop"  
  5.     xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  7.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd  
  8.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">  
  9.   
  10.     <!-- 配置远程JNDI数据源-->  
  11.     <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">  
  12.         <property name="jndiName" value="xpDS" />  
  13.         <property name="jndiEnvironment">  
  14.             <props>  
  15.                 <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>  
  16.                 <prop key="java.naming.provider.url">t3://127.0.0.1:7001</prop>  
  17.                 <prop key="java.naming.security.principal">weblogic</prop>  
  18.                 <prop key="java.naming.security.credentials">weblogic</prop>  
  19.             </props>  
  20.         </property>  
  21.     </bean>  
  22.                 <!-- ibatis sqlMapClient -->  
  23.     <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">  
  24.         <property name="configLocation" value="classpath:sql-map-config.xml"/>  
  25.         <property name="dataSource" ref="jndiDataSource"/>  
  26.     </bean>  
  27.                 <!-- 引入bo配置文件 -->  
  28.     <import resource="classpath:/config/dmtab.xml" />  
  29. </beans>  

 

 

在Spring的applicationContext.xml文件中未进行任何关于事务管理方面的配置

 

EJB方法代码:

Java代码  收藏代码
  1. public class HelloBean implements javax.ejb.SessionBean {  
  2.   
  3. ...  
  4.   
  5.                 public String saveDM_DWLX(DM_DWLX param) {  
  6.         DM_DWLX temp = new DM_DWLX();  
  7.         temp.setDWLX_DM("89");  
  8.         temp.setDWLX_MC("政府机关");  
  9.         boDM_DWLX.insertDM_DWLX(temp);//保证能够成功插入数据库  
  10.         boDM_DWLX.insertDM_DWLX(param);//模拟插入失败情况  
  11.         return null;  
  12.     }  
  13.   
  14. ...  
  15.   
  16. }  

 注意:这里的两次插入操作都是在ejb方法中进行的,如果将这两 次插入操作移植到boDM_DWLX.insertDM_DWLX(DM_DWLX param)方法中完成,那么事务就不能正常回滚了。因此,通过ejb控制事务时,ejb方法就变成了业务方法,封装了一个业务对应的各种操作,和项目技 术架构中使用ejb只作为facade和实现分布式的应用相违背,而且,每当业务发生变化都需要修改EJB,为系统修改造成极大的不方便。

 

ejb-jar.xml文件配置:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">  
  4.   
  5.    <description</description>  
  6.    <display-name>EJBTest</display-name>  
  7.   
  8.    <enterprise-beans>        
  9.       <!-- Session Beans -->  
  10.       <session id="Session_Hello">  
  11.          <description><![CDATA[An EJB named Hello]]></description>  
  12.          <display-name>Hello</display-name>  
  13.   
  14.          <ejb-name>Hello</ejb-name>  
  15.   
  16.          <home>net.xp.service.ejb.HelloHome</home>  
  17.          <remote>net.xp.service.ejb.Hello</remote>  
  18.          <local-home>net.xp.service.ejb.HelloLocalHome</local-home>  
  19.          <local>net.xp.service.ejb.HelloLocal</local>  
  20.          <ejb-class>net.xp.service.ejb.HelloBean</ejb-class>  
  21.          <session-type>Stateless</session-type>  
  22.          <transaction-type>Container</transaction-type><!--注意:此处选择的是容器管理事务-->  
  23.   
  24.       </session>  
  25.    </enterprise-beans>  
  26.    <container-transaction><!--容器事务属性配置(必须的,否则事务将无法控制)-->  
  27.       <description></description>  
  28.       <method>  
  29.         <description></description>  
  30.         <ejb-name>Hello</ejb-name>  
  31.         <method-name>*</method-name>  
  32.       </method>  
  33.       <trans-attribute>Required</trans-attribute>  
  34.    </container-transaction>  
  35.    ...  
  36.   
  37. </ejb-jar>  

 

客户端测试代码:

Java代码  收藏代码
  1. public static void main(String[] args) throws Exception {  
  2.         Properties p = new Properties();  
  3.         p.put("java.naming.factory.initial""weblogic.jndi.WLInitialContextFactory");  
  4.         p.put("java.naming.provider.url","t3://127.0.0.1:7001");  
  5.         InitialContext ctx = new InitialContext(p);  
  6.         Object obj = ctx.lookup("Hello");  
  7.         HelloHome home = (HelloHome)PortableRemoteObject.narrow(obj, HelloHome.class);  
  8.         Hello hello = home.create();  
  9.           
  10.         DM_DWLX model = new DM_DWLX();  
  11.         model.setDWLX_DM("AAa");//模拟字段长度过长异常  
  12.         model.setDWLX_MC("AA");  
  13.         hello.saveDM_DWLX(model);  
  14. }  

 

测试结果:

在ejb方法saveDM_DWLX中,第一次插入操作成功,但第二次插入操作失败情况下,事务成功回滚

 

2)通过Spring2的声明式事务在业务层进行事务控制

Spring提供了两种事务管理方式,即编程式事务和声明式事务,这里主要记录使用声明式事务的配置

 

Spring声明式事务配置代码:

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop"  
  5.     xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  7.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd  
  8.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">  
  9.   
  10.     <!-- 配置远程JNDI数据源-->  
  11.     <bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">  
  12.         <property name="jndiName" value="ds" />  
  13.         <property name="jndiEnvironment">  
  14.             <props>  
  15.                 <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>  
  16.                 <prop key="java.naming.provider.url">t3://127.0.0.1:7001</prop>  
  17.                 <prop key="java.naming.security.principal">weblogic</prop>  
  18.                 <prop key="java.naming.security.credentials">weblogic</prop>  
  19.             </props>  
  20.         </property>  
  21.     </bean>  
  22.        
  23.     <!-- ibatis sqlMapClient -->  
  24.     <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">  
  25.         <property name="configLocation" value="classpath:sql-map-config.xml"/>  
  26.         <property name="dataSource" ref="jndiDataSource"/>  
  27.     </bean>  
  28.     <!-- 事务管理器 -->  
  29.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  30.         <property name="dataSource" ref="jndiDataSource"/>  
  31.     </bean>  
  32.                 <!--jta事务管理器,需要进行全局事务时配置,使用jta事务,要求上面的jndi datasource配置成XA DataSource  
  33.                 <bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">  
  34.     </bean>  
  35.       
  36.     -->  
  37.                 <!--aop配置,这里主要设置对bo包下的类和业务方法进行事务控制-->  
  38.     <aop:config>  
  39.         <aop:pointcut id="defaultServiceOperation" expression="execution(* net.xp.service.bo..*.*(..))"/>  
  40.         <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>  
  41.     </aop:config>  
  42.     <!--事务通知,针对不同方法配置事务属性-->    
  43.     <tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">-->  
  44.     <!-- <tx:advice id="defaultTxAdvice">  
  45.         <tx:attributes>  
  46.             <tx:method name="get*" read-only="true" rollback-for="Exception"/>  
  47.             <tx:method name="select*" read-only="true" rollback-for="Exception"/>  
  48.             <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>  
  49.             <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>  
  50.             <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>  
  51.             <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>  
  52.             <tx:method name="make*" propagation="REQUIRED" rollback-for="Exception"/>  
  53.         </tx:attributes>  
  54.     </tx:advice>  
  55.       
  56.       
  57.     <!-- 引入bo配置文件 -->  
  58.     <import resource="classpath:/config/dmtab.xml" />  
  59. </beans>  

 

使用该配置,事务将在bo层进行控制,符合在业务层进行事务控制的要求,且配置和应用简单,推荐使用该方案进行项目中的事务控制

 

3)通过IBatis对DAO层的事务进行控制

 

2、基于Spring的EJB开发

虽然Spring提供了很多帮助实现EJB的类,但实现起来那叫一个麻烦,引用Spring官方文档翻译后中的一段文字:

 

“与不使用Spring方式的EJB客户端相比,Spring的EJB客户端有一个额外的好处。通常如果要想能随意的在本地和远程EJB调用之间切换EJB客户端代码,是会产生问题的。这是因为远程接口的方法需要声明他们抛出的RemoteException方 法,然后客户端代码必须处理这种异常,但是本地接口的方法却不需要这样。如果要把针对本地EJB的代码改为访问远程EJB,就需要修改客户端代码,增加处 理远程异常的代码,反之要么保留这些用不上的远程异常处理代码要么就需要进行修改以去除这些异常处理代码。使用Spring的远程EJB代理,我们就不再 需要在业务方法接口和EJB的实现代码中声明要抛出的RemoteException,而是定义一个相似的远程接口,唯一不同就是它抛出的是RemoteException, 然后交给代理对象去动态的协调这两个接口。也就是说,客户端代码不再需要与 RemoteException这个checked exception打交道,实际上在EJB调用中被抛出的RemoteException都将被

以unchecked exception RemoteAccessException的方式重新抛出,它是RuntimeException的一个子类。这样目标服务就可以在本地EJB或远程EJB(甚至POJO)之间随意地切换,客户端不需要关心甚至根本不会觉察到这种切换。当然,这些都是可选的,没有什么阻止你在你的业务接口中声明RemoteExceptions异常。”

 

刚开始看到这段文字的确让我感到一种久违的兴奋,但经过编写代码实践却发现根本不是这么回事,实现本地EJB时客户端的确不需要捕获任何异常,但是 实现远程EJB时客户端仍然要捕获RemoteException,在官方文档中只提供了本地EJB调用的部分代码,并没有提供远程EJB调用的代码,突 然感觉有种被忽悠的感觉,在网上找了很多文章,只有问的,却没见到有回答的,真是让人不解~~

 

如果有哪位高人知道,可以给我回复,分享你的理解,在此先谢过

 

 

3、EJB本地接口和远程接口调用

 

 EJB远程接口调用就不说了,主要说说EJB本地接口调用吧,以前在项目中都使用的是远程接口调用,从来没有使用本地接口调用,想着简单,就随便写了点代码试验一把,不试不知道,一试吓一跳,居然碰了一鼻子的灰,一直报NameNotFoundException。 最终将用于调用EJB本地接口的Servlet和ejb打包成EAR包部署后测试成功,一直不理解为什么将web和ejb分别以war和jar方式部署在 WebLogic的同一个domain下就不行了呢,呵呵,还得等待好心的高人给予解答~~

推荐一篇相关的文章http://www.iteye.com/topic/270490 供大家参考

分享到:
评论

相关推荐

    Struts2.0+Springframework2.5+ibatis2.3完美整合用户登录及增删改查

    本演示示例主要使用目前最新,最流行技术Struts2.1 +Spring 2.5.1+ibatis2.3整合开发而成,这与我以前发布的版本中最大特色是整合了Spring2.5.1中的注解功能和半自动化工具ibatis技术,这是本示例的两大特色,简化了配置...

    java拦截器

    spring=非标准的J2EE技术实现(很多开源的Framwork)。 Sun标准:J2EE技术,Servlet、JSP、JPA、JTA、JavaMail、EJB、JSF、JDBC和JPA。。...struts+spring+ibatis struts+spring+jdbc webWork+spring+

    JSF+Spring+JPA(Hibernate实现)的环境搭建

    JSF+Spring+JPA以我个人看来,应该说是Struts2+Spring+Hibernate的替代解决方案。 引入JPA去取代或者说包装或者说是升级Hibernate是为了符合JAVA EE的规范,达到ORM统一的结果。下次项目用EJB也好、用TOPLINK也好、...

    Spring in Action(第二版 中文高清版).part2

    16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...

    Spring in Action(第2版)中文版

    16.2协同使用spring和webwork2/struts2 16.3集成spring和tapestry 16.3.1集成spring和tapestry3 16.3.2集成spring和tapestry4 16.4协同使用spring和jsf 16.4.1解析jsf管理的属性 16.4.2解析springbean 16.4.3...

    Spring-Reference_zh_CN(Spring中文参考手册)

    2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的...

    spring4.3.2参考文档(英文)

    通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。 Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常...

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    Spring 2.0的'spring-jdo.jar', 'spring-jpa.jar', 'spring-hibernate3.jar', 'spring-toplink.jar' 和 'spring-ibatis.jar' 被合并到Spring 2.5大粒度的'spring-orm.jar'中。 Spring 2.5的 'spring-test.jar' 取代...

    Spring 2.0 开发参考手册

    2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@...

    spring jar 包详解

    (11) spring-web.jar 这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、 Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 (12) ...

    Spring in Action(第二版 中文高清版).part1

    16.2 协同使用Spring和WebWork 2/Struts 2 16.3 集成Spring和Tapestry 16.3.1 集成Spring和Tapestry 3 16.3.2 集成Spring和Tapestry 4 16.4 协同使用Spring和JSF 16.4.1 解析JSF管理的属性 16.4.2 解析Spring...

    Spring in Action中文版 清晰pdf part2

    Spring是以反向控制设计原理为基础,无需EJB而功能依然强大的轻量级J2EE开发框架。Spring大大简化了使用接口开发的复杂性,并且加快和简化了应用系统的开发。使用简单JavaBean就可以得到EJB的强大功能。 本书介绍了...

    最新最全的spring开发包

     这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 (12) spring-webmvc.jar 这个...

    spring4.3.9相关jar包

    spring-web.jar(必须) :这个jar 文件包含Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。...

    Spring In Action中文 第六部分

    中文版.part2.rar Spring in Action. 中文版.part3.rar Spring in Action. 中文版.part4.rar Spring in Action. 中文版.part5.rar Spring in Action. 中文版.part6.rar Spring in Action. 中文版....

    Spring In Action中文 第七部分

    中文版.part2.rar Spring in Action. 中文版.part3.rar Spring in Action. 中文版.part4.rar Spring in Action. 中文版.part5.rar Spring in Action. 中文版.part6.rar Spring in Action. 中文版....

    Spring In Action中文 第五部分

    中文版.part2.rar Spring in Action. 中文版.part3.rar Spring in Action. 中文版.part4.rar Spring in Action. 中文版.part5.rar Spring in Action. 中文版.part6.rar Spring in Action. 中文版....

    spring chm文档

    Spring Framework 开发参考手册 Rod Johnson Juergen Hoeller Alef Arendsen Colin Sampaleanu Rob Harrop Thomas Risberg Darren Davison Dmitriy Kopylenko Mark Pollack Thierry Templier Erwin ...

    spring-framework-3.0.5.RELEASE-dependencies-2

    spring-framework-3.0.5.RELEASE-dependencies 好不容易找到了,赶紧分享一下 因为不能大于20M,共分了8个包,都是独立的,我列了目录, 可以只下载需要的包,这是2号包: 1号包: edu.emory.mathcs.backport edu.oswego....

Global site tag (gtag.js) - Google Analytics