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

测试情形二:
web层捕获异常并处理,Service捕获异常并处理,DAO层不捕获异常.

修改StudentManagerServiceImp类


代码
public class StudentManagerServiceImp implements StudentManagerService{
private StudentDAO stdDAO;

public void setStdDAO(StudentDAO stdDAO){
this.stdDAO=stdDAO;
}

//此方法为事务型的,删除student1中的记录成功且插入student2的记录也成功
 //如果insertStudent2()方法执行失败,那么deleteStudent1()也应该会失败
public void bus_method(){
try{
this.stdDAO.deleteStudent1();
this.stdDAO.insertStudent2();
}
catch(DataAccessException de)
System.err.println("service execute exception!");
}
}

}
运行程序:启动服务器,并部署.进入index.jsp页面,点击"执行"超链接"---->页面跳向chenggong.jsp
查看控制台:打印有:service execute exception!
查看数据库: student1表中的[1 xiaoming wuhan] 记录不存在,student2表仍然为空.
小结:如果Service捕获异常并处理而不向外抛出,web层捕获不到异常,spring事务管理失败!

测试情形(还原表中的数据)三:
web层捕获异常,Service捕获异常,DAO层也捕获异常.

修改StudentDAOImp类代码


代码
public class StudentDAOImp extends JdbcDaoSupport implements StudentDAO{
//删除student1表中的id=1的记录
public void deleteStudent1(){
try{
     JdbcTemplate jt=this.getJdbcTemplate();
     jt.update("delete from student1 where id=1");
}
catch(DataAccessException e){
System.err.println("dao deleteStudent1 execute exception!");
}
   }

//将student1表中删除的记录插入到student2中,但是此方法实现有错,因为
   //id字段设置为自增长的,所以在插入记录时我们不能指定值
  public void insertStudent2(){
try{
       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);
}
catch(DataAccessException e){
System.err.println("dao insertStudent2 execute exception!");

}
}

}
运行程序:启动服务器,并部署.进入index.jsp页面,点击"执行"超链接"---->页面跳向chenggong.jsp
查看控制台:打印有:dao insertStudent2 execute exception!
查看数据库: student1表中的 1,xiaoming,wuhan 记录不存在,student2表仍然为空.
小结如果DAO的每一个方法自己捕获异常并处理而不向外抛出,Service层捕获不到异常,Web层同样捕获不到异常,spring事务管理失败!

测试情形四:

还原数据库中的数据
还原StudentDAOImp类中的方法为测试情形一中的实现
web层捕获异常Service抛出的自定义异常StudentManagerException
Service捕获DataAccessException并抛出StudentManagerException,
StudentManagerException为DataAccessException的子类
DAO层不捕获异常

修改StudentManagerServiceImp类的实现:


代码
public class StudentManagerServiceImp implements StudentManagerService{
private StudentDAO stdDAO;

public void setStdDAO(StudentDAO stdDAO){
this.stdDAO=stdDAO;
}

//此方法为事务型的,删除student1中的记录成功且插入student2的记录也成功
 //如果insertStudent2()方法执行失败,那么deleteStudent1()也应该会失败
public void bus_method() throws StudentManagerException{
try{
this.stdDAO.deleteStudent1();
this.stdDAO.insertStudent2();
}
catch(DataAccessException de)
System.err.println("service execute exception!");
     throw new StudentManagerException();//StudentManagerException类继承DataAcce                          //ssException异常
}
}
}
修改StudentManagerAction


代码
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(StudentManagerException e){
System.err.println("action execute service exception!");
return mapping.findForward("shibai");
}

}
}

运行程序:启动服务器,并部署.进入index.jsp页面,点击"执行"超链接"---->页面跳向shibai.jsp
查看控制台:打印有:service execute exception!
action execute service exception!
查看数据库: student1表中的 [1,xiaoming,wuhan] 记录仍然存在,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层捕获,这样我们就可以手动编码的灵活实现通过业务方法执行的成功和失败 来向用户转发不同的页面.
来源:http://www.iteye.com/topic/34867
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值