`
daodan988
  • 浏览: 31571 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

[转]关于spring声明式事务管理异常处理的测试和小结一

阅读更多
关于spring事务管理以及异常处理的帖子,本论坛争论颇多,各有各的测试代码,也各有各的测试结果,
不知道是spring版本的不同还是各测试的例子的不同而导致测试结果出现差异.
本人也很想弄清楚spring是如何对Service进行事务管理的,并且还去看了一下spring框架关于事务管理几个相关类的源码,可惜由于本人功力有限,只看懂了皮毛.
既然源代码看不懂,那么只有运用例子进行测试,虽然笨了点,不过管是白猫还是黑猫,能捉老鼠就是好猫.:)
为引起不必要的争论,本帖子只针对本案例的测试结果进行小结,并保证此测试代码在本人的运行环境绝对正确.

开发环境:
OS:windows 2003 Server
Web Server: jakarta-tomcat-5.0.28
DataBase Server: MS SQL Server 2000 (打了SP3补丁)
IDE: Eclipse 3.2.0+MyEclipse 5.0GA

测试案例系统结构:
web层<---->Service层<---->DAO层

web层使用struts 1.1,DAO使用的spring的JDBC,spring版本1.2

数据库中有两张表:
student1和Student2,表结构相同:id,name,address.其中id为主键且为自增长型.
student1表中有一条记录:


代码
id   name        address   
1    xiaoming     wuhan   
  
student2表中记录为空 
测试情形一:
web层捕获异常并处理,DAO层不捕获异常,Service也不捕获异常.

Service层接口:


代码
public interface StudentManagerService {   
     
    public void   bus_method();   

DAO层接口


代码
public interface StudentDAO {   
     
    public void   deleteStudent1();   
    public void   insertStudent2();   

StudentDAO接口的实现:


代码
public class StudentDAOImp extends JdbcDaoSupport implements StudentDAO{   
     //删除student1表中的id=1的记录   
     public void   deleteStudent1(){   
     JdbcTemplate jt=this.getJdbcTemplate();   
     jt.update("delete from student1 where id=1");        
   }   
        
     //将student1表中删除的记录插入到student2中,但是此方法实现有错,因为   
   //id字段设置为自增长的,所以在插入记录时我们不能指定值   
       public void   insertStudent2(){   
       JdbcTemplate jt=this.getJdbcTemplate();   
             String arg[]=new String[3];   
        arg[0]="1";   
             arg[1]="xiaoming";   
        arg[2]="wuhan";   
             jt.update("insert student2(id,name,address) values(?,?,?)",arg);   
      }   
  
}  
StudentManagerService 接口的实现:


代码
public class StudentManagerServiceImp implements StudentManagerService{   
  private StudentDAO   stdDAO;   
  
  public void setStdDAO(StudentDAO    stdDAO){   
     this.stdDAO=stdDAO;   
   }   
      
  //此方法为事务型的:删除student1中的记录成功且插入student2的记录也成功,   
 //如果insertStudent2()方法执行失败,那么deleteStudent1()方法也应该会失败   
  public void   bus_method(){   
    this.stdDAO.deleteStudent1();   
    this.stdDAO.insertStudent2();   
   }   
     
}  
web层:
三个jsp,一个action:
index.jsp ==>首页面.上面仅仅有一个超链接<a herf="test.do">执行</a>
chenggong.jsp ==>Service执行成功后转向的JSP页面
shibai.jsp ====>Service执行失败后转向的JSP页面

action实现:


代码
public class StudentManagerAction  extends   Action{   
  
     public ActionForward execute(ActionMapping mapping, ActionForm form,   
     HttpServletRequest request, HttpServletResponse response) {   
         try{   
              WebApplicationContext appContext=WebApplicationContextUtils.   
                   getWebApplicationContext(this.getServlet().getServletContext());   
         StudentManagerService stdm=(StudentManagerService)appContext.   
                                         getBean("stdServiceManager");   
             stdm.bus_method();   
            return mapping.findForward("chenggong");   
      }   
     catch(DataAccessException e){   
         System.err.println("action execute service exception!");   
        return mapping.findForward("shibai");   
       }   
  
     }   

配置文件:

web.xml


代码
<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  <context-param>  
    <param-name>log4jConfigLocation</param-name>  
    <param-value>/WEB-INF/log4j.properties</param-value>  
  </context-param>  
  <context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>/WEB-INF/applicationContext.xml</param-value>  
  </context-param>  
  <listener>  
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
  </listener>  
  <listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  </listener>  
  <servlet>  
    <servlet-name>action</servlet-name>  
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
    <init-param>  
      <param-name>config</param-name>  
      <param-value>/WEB-INF/struts-config.xml</param-value>  
    </init-param>  
    <init-param>  
      <param-name>debug</param-name>  
      <param-value>3</param-value>  
    </init-param>  
    <init-param>  
      <param-name>detail</param-name>  
      <param-value>3</param-value>  
    </init-param>  
    <load-on-startup>0</load-on-startup>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>action</servlet-name>  
    <url-pattern>*.do</url-pattern>  
  </servlet-mapping>  
</web-app> 
sturts-config.xml


代码
<struts-config>  
  <action-mappings >  
    <action  input="/index.jsp"  path="/test"  type="test.StudentManagerAction   >  
      <forward name="chenggong" path="/chenggong.jsp" />  
      <forward name="shibai" path="/shibai.jsp" />  
    </action>  
  </action-mappings>  
  <message-resources parameter="test.ApplicationResources" />  
</struts-config> 
applicationContext.xml


代码
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
<beans>  
    <bean id="dataSource"  
      class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >  
      <property name="driverClassName" value="com.microsoft.jdbc.sqlserver.SQLServerDriver"></property>  
      <property name="url" value="jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=test"></property>  
       <property name="username" value="sa"></property>  
       <property name="password" value="sa"></property>  
    </bean>  
       
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource"/>  
     </bean>  
           
    <bean id="baseTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  lazy-init="true">  
        <property name="transactionManager">  
        <ref bean="transactionManager" />  
         </property>  
         <property name="transactionAttributes">  
         <props>  
             <prop key="*">PROPAGATION_REQUIRED</prop>  
        </props>  
         </property>  
    </bean>  
  
    <bean id="stdServiceManager"  parent="baseTxProxy" >  
        <property name="target">  
             <bean class="test.StudentManagerServiceImp">       
                       <property name="stdDAO">  
                      <ref bean="stdDAO"/>  
                       </property>       
                  </bean>   
        </property>   
    </bean>  
  
    <bean id="stdDAO" class="test.StudentDAOImp">  
       <property name="dataSource" ref="dataSource"/>  
    </bean>  
</beans> 
运行程序:启动服务器,并部署.进入index.jsp页面,点击"执行"超链接"---->页面跳向shibai.jsp
查看控制台:打印有:action execute service exception!
查看数据库: student1表中的[1 xiaoming wuhan] 记录仍然存在,student2表仍然为空.
小结:如果DAO层和Service不捕获异常而在web层捕获异常,web成功捕获异常,spring事务管理成功!
分享到:
评论

相关推荐

    Spring.3.x企业应用开发实战(完整版).part2

    9.6 使用注解配置声明式事务 9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 ...

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

    6.4 声明式事务 6.4.1 定义事务参数 6.4.2 代理事务 6.4.3 在Spring 2.0里声明事务 6.4.4 定义注释驱动事务 6.5 小结 第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider ...

    Spring攻略(第二版 中文高清版).part1

    13.6 管理集成测试中的事务 530 13.6.1 问题 530 13.6.2 解决方案 530 13.6.3 工作原理 531 13.7 在集成测试中访问数据库 536 13.7.1 问题 536 13.7.2 解决方案 536 13.7.3 工作原理 537 13.8 使用...

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

    6.4 声明式事务 6.4.1 定义事务参数 6.4.2 代理事务 6.4.3 在Spring 2.0里声明事务 6.4.4 定义注释驱动事务 6.5 小结 第7章 保护Spring 7.1 Spring Security介绍 7.2 验证用户身份 7.2.1 配置Provider ...

    Spring3.x企业应用开发实战(完整版) part1

    9.6 使用注解配置声明式事务 9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 ...

    Spring in Action(第2版)中文版

    6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2...

    Spring 2.0 开发参考手册

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

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

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.6.1. @Transactional 有关的设置 ...

    Spring攻略(第二版 中文高清版).part2

    13.6 管理集成测试中的事务 530 13.6.1 问题 530 13.6.2 解决方案 530 13.6.3 工作原理 531 13.7 在集成测试中访问数据库 536 13.7.1 问题 536 13.7.2 解决方案 536 13.7.3 工作原理 537 13.8 使用...

    Spring API

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    Spring中文帮助文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    spring chm文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

    SSI框架整合小结

    - Spring提供了一套完善的事务管理机制,可以通过声明式事务管理或编程式事务管理来实现。 #### 四、总结 本文详细介绍了在SSI框架环境下,一个典型的操作是如何被执行的。从请求的接收、处理到响应的生成,每...

    web应用dao层的开发经验小结

    Spring框架提供了声明式事务管理,可以在方法上添加@Transactional注解,简化事务控制。 6. 异常处理 DAO层应捕获并封装数据库操作可能抛出的异常,如SQLException,转化为业务友好的异常类型,如...

    SSM集成应用

    - **Spring中事务AOP的配置**:通过声明式事务管理实现。 - **Spring+MyBatis业务实现**:结合Spring和MyBatis进行业务逻辑处理。 #### SpringMVC配置详解 **10.1 SpringMVC web模型** SpringMVC的工作流程。 **...

    javaSE代码实例

    1.5 小结 11 第2章 基本数据类型——构建Java 大厦的基础 12 2.1 源代码注释 12 2.1.1 单行注释 12 2.1.2 区域注释 12 2.1.3 文档注释 13 2.2 基本数据类型 14 2.2.1 整型 15 2.2.2 浮点型 17 ...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    其中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,控制业务跳转,利用Hibernate框架对持久层提供支持,Spring做管理,管理Struts和Hibernate。 WebStorage HTML新增的本地存储解决...

Global site tag (gtag.js) - Google Analytics