转自:http://blog.csdn.net/linlzk/article/details/4355993
开发环境:
OS:windows XP
Web Server: jakarta-tomcat-5.0.28
DataBase Server: MS SQL Server 2000 (打了SP3补丁)
IDE: MyEclipse 6.0.1
测试案例系统结构:
web层<---->Service 层<---->DAO 层
web层就是Struts2,DAO 使用hibernate -3.3.1.GA-dist.zip,spring 是spring -framework-2.5.5
数据库表和它一样吧:
student1和Student2,表结构相同:id,name,address.其中id为主键且为自增长型.
student1表中有一条记录:
测试情形一:
web层捕获异常并处理,DAO 层不捕获异常,Service 也不捕获异常.
Service 层接口:
public interface Student1Service { void addStudent1(Student1 stu); } public interface StudentSService { void addStudent2(Student2 stu) throws SaveException; }
Service 实现
public void addStudent1(Student1 stu) { stufDAO.insertStuF(stu); } public void addStudent2(Student2 stu) throws SaveException { String[] aa={"ww","ww","ww"}; for(int i=0;i<5;i++){ //出错 System.out.println(aa[i]); } stusDAO.insertStuS(stu); }
DAO 层接口
public interface StudentFDAO { void insertStuF(Student1 stu); } public interface StudentSDAO { void insertStuS(Student2 stu); }
DAO 实现
public void insertStuF(Student1 stu) { getHibernateTemplate().save (stu); } public void insertStuS(Student2 stu) { getHibernateTemplate().save (stu); }
Action
public String execute() throws Exception{ Student1 sti=new Student1(stu1Name,stu1Address); Student2 stu=new Student2(stu1Name,stu1Address); try{ studentfService.addStudent1(sti); studentsService.addStudent2(stu); }catch(DataAccessException e){ System.out.println(“error”); return “failer”: } return SUCCESS; }
JSP
<form action="testaction.action" method="POST"> <table> <tr><td>名:</td><td><input type="text" value="stu1Name" name="stu1Name"></td></tr> <tr><td>地址:</td><td><input type="text" value="stu1Address" name="stu1Address"></td></tr> <Tr><td></td><td><input type="submit" value="提交" style="width:80px"></td></Tr> </table> </form>
配置文件
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> <!-- 定义BeanNameAutoProxyCreator--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>st1Service</value> <value>stsService</value> </list> </property> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean>
运行程序:启动服务器,并部署.进入index.jsp页面,点击提交
查看数据库: 两个表中都没有新增数据。
小结:如果DAO 层和Service 不捕获异常而在web层捕获异常,web成功捕获异常(抛不抛出都行),spring 事务管理成功!
二、Service 层捕捉异常,DAO 不捕捉异常(下面就简单一点了,直接给结论把)
1.如果,你在Service 捕捉异常而不抛出异常,Action层捕捉不到异常,那么事物处理失败。
2.如果在Service 捕捉异常并且抛出异常,那么,如果抛出的异常是Checked异常(自定义的),不会回滚。也正好验证了Spring 事物里的这段话:默认情况下,事物只会出现运行异常(runtime exception)时回滚,而出现受阻异常(checked exception)时不回滚。
3.如果抛出的异常是RuntimeChecked异常(自定义的),那么事物处理成功。
所以如果你的抛出的异常是CheckException,你配置事物的时候必须加上-Exception参数,指定出现Checked异常时回滚,也就是PROPAGATION_REQUIRED,-Exception。
三、DAO 捕获异常
如果DAO 捕捉异常而不抛出异常,Action层捕捉不到异常,Service 捕获不到异常。
运行程序:启动服务器,并部署.进入index.jsp页面,点击提交
查看数据库:student1表中新曾数据,Student2表中都没有数据。事务处理失败。
小结:
前面的文章中提到,如果DAO 的每一个方法不捕获异常,Service 层捕获DataAccessException异常并抛出自己定义异常(自定义异常为DataAccessException的子类),Web层可以捕获到异常,spring 事务管理成功!
然后在总结中说:
1.spring 在进行声明时事务管理时,通过捕获Service 层方法的DataAccessException来提交和回滚事务的,而Service 层方法的DataAccessException又是来自调用DAO 层方法所产生的异常.
2.我们一般在写DAO 层代码时,如果继承JdbcDaoSupport 类,并使用此类所实现的JdbcTemplate来执行数据库操作,此类会自动把低层的SQLException转化成DataAccessException以及DataAccessException的子类.
3.一般在Service 层我们可以自己捕获DAO 方法所产成的DataAccessException,然后再抛出一个业务方法有意义的异常(ps:此异常最好继承DataAccessException),然后在Web层捕获,这样我们就可以手动编码的灵活实现通过业务方法执行的成功和失败来向用户转发不同的页面
其实这到不是因为自定义异常为DataAccessException的子类,而是DataAccessException是 RuntimeException,那么它的子类也是Runtime,所以抛出异常是会回滚的。所以你的自定义异常继承自 RuntimeException也可以。
再发表一些个人看发吧,在Spring 中所有数据库操作异常都转换为DataAccessException这个运行时异常,不过在业务层中也有可能抛出一些其他的运行时异常,那么这时候在一些简单的项目中,我们直接用下面的方式也未尝不可:
Java代码
try{ ……. ……… ……..(可能会有其他运行时异常,并不仅仅是DataAccessException) }catch(Exception e){ log.error(“error”); throw new CheckedException(“error”); //抛出受检查异常 }
然后在Action层捕捉这个受检查异常
Java代码
try{ service.method(); }catch(CheckedException e){ }
这个异常,它是可以被调用者正确处理的。返回相应的提示。当然,如果抛出CheckException,那么Spring 声明式事物的时候就应该加上-Exception参数,前面已经提到。
当然在一些业务逻辑比较复杂,并且要根据复杂的逻辑返回不同的试图的时候,这样整个的try{}catch(){}就不合适了,这时候应该将不正常的事件流转换为运行时异常,并且在方法声明中详细的说明该方法可能会抛出的unChekced异常。由调用者自己去决定是否捕获unChecked异常 ,返回相应的视图。
总结:
1.一般DAO 中不捕捉异常也不抛出异常
2.至于Service 层和Action层,是在service 层抛出CheckException然后由action捕捉,还是在service 中全部采用unCheckException,然后在action中有选择的捕捉或者都不捕捉就要看你自己的选择了, 个人认为逻辑比较简单的可以选择前者,比较复杂就选择后者。
3.禁忌捕捉异常而不做任何处理(如果是dao 层或者service 层,最好抛出),不然很有可能造成事务处理失败。
相关推荐
通过本文介绍的自定义异常处理逻辑,可以有效解决Spring Cloud Gateway默认异常处理机制中存在的问题,使得异常信息更加符合业务需求。此外,这种方式也为开发者提供了一个良好的起点,可以根据具体项目需求进一步...
详解 SpringCloud Finchley Gateway 统一异常处理 SpringCloud Finchley Gateway 统一异常处理是指在使用 SpringCloud Finchley 版本的 Gateway 时,如何统一处理系统级异常的方法。默认情况下,SpringCloud ...
3.处理日志时,需要在每一个try-catch块包含一些处理代码,有时候异常处理的代码比正常执行代码还多,污染正常执行代码。 4.同样类型异常有不同的处理方式,使最终的处理变得复杂。 5.接口抛出异常,破坏封装,打破...
本文将深入探讨Spring MVC中的异常处理机制,帮助你更好地理解如何优雅地处理错误和异常。 1. **Spring MVC 异常处理概述** Spring MVC 提供了一种统一的方式来处理应用程序中抛出的异常。它通过`@...
Spring Boot统一异常处理类,BaseResponse类就两个字段code和message。经测试,可以捕获所以异常,并返回指定json数据
Spring Boot 提供了统一的异常处理机制,通过使用 @ControllerAdvice 和 @ExceptionHandler 注解,可以实现对控制器层、Service 层、Dao 层以及 Spring 系统内定义的部分异常的统一处理。 在 Spring Boot 中,可以...
spring 异常统一处理类.doc ok
本篇文章将深入探讨Spring中的数据库异常处理机制,帮助开发者更好地理解和处理在数据库操作中可能遇到的问题。 首先,Spring Data Access层的核心组件是JdbcTemplate和HibernateTemplate(或其升级版JPA的...
在Spring MVC框架中,异常处理是一项关键任务,它确保了应用程序在遇到错误或异常时能够优雅地响应。本文将深入探讨Spring MVC中的异常处理机制,包括如何配置、自定义异常处理器以及异常转换策略。 首先,Spring ...
spring mvc统一处理异常,通过@ControllerAdvice+@ExceptionHandler
在Spring Boot应用中,全局异常处理是至关重要的一...通过以上步骤,你可以在Spring Boot应用中实现全面且优雅的全局异常处理,确保系统在出现问题时仍能提供一致的反馈,增强用户体验,同时便于开发者调试和排查问题。
8. **日志记录**:异常处理也涉及到日志记录,确保关键错误信息被记录下来供调试和问题排查。Spring Boot的`logging`配置可以帮助我们定制日志级别和输出格式。 9. **测试**:为了验证异常处理机制是否有效,项目的...
3. 异常处理:对线程池中的异常进行捕获和处理,防止异常导致整个应用崩溃。 4. 监控和调优:通过Spring Boot Actuator等监控工具,实时查看线程池状态,根据实际运行情况调整配置。 总结,使用Spring MVC和Spring...
内容概要:本文详细介绍了Spring Boot的异常处理机制,包括Java标准异常、Spring框架异常和自定义异常的处理方式。文章讲解了如何创建自定义异常类,配置全局异常处理器,并通过@ControllerAdvice和@...
Spring Cloud Gateway全局异常处理的方法详解 Spring Cloud Gateway作为Spring Cloud生态系中的网关,旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。然而,在实际应用中,Spring Cloud Gateway中的...
统一异常处理会区分前端是否ajax请求,自动返回json数据格式,要求开发人员在处理ajax请求时统一封装成一个对象返回,以符合代码统一规范。 此工程在idea环境编写,导入请自己新建工程手工复制代码导入。
在这个“springboot整合thymeleaf+maven实现异常处理页面”的案例中,我们将探讨如何在 SpringBoot 应用中整合 Thymeleaf 和 Maven,以及如何设置自定义的全局异常处理机制,使得当应用程序出现异常时,能够优雅地将...
在Spring框架中,异常处理是应用程序健壮性的重要组成部分,确保在遇到错误或异常情况时,能够提供合适的反馈和日志记录。本文将详细介绍Spring中处理异常的几种方式,并探讨它们的优缺点。 1. **@Controller + @...
tedu二阶段Spring的异常处理