测试@Transactional的在处理异常时是否生效,
首先这里随便写一个update的方法,对数据库进行更新操作,然后在操作完之后抛一个异常
@Override
@Transactional(rollbackFor = {Exception.class})
public String alterUser(){
try {
User user=new User();
user.setId(2);
user.setUsername("updateUserTest");
userMapper.updateByPrimaryKeySelective(user);
int i=1/0;
return "success";
}catch (Exception e){
return "false";
}
}
这里在update完之后,抛一个ArithmeticException(除0),按照我们设想的,这里出现了异常,然后事务回滚,更新不会生效
,然后我们测试一下
原来数据库中的记录是这样的
这里我们写的接口,返回了false,说明是补获到异常了。
然后看下数据库
这里可以看到记录还是被修改了,事务没有回滚。
然后我们将异常抛出去,不处理
在控制器中处理
@Override
@Transactional(rollbackFor = {Exception.class})
public String alterUser() throws Exception{
try {
User user=new User();
user.setId(2);
user.setUsername("updateUser");
userMapper.updateByPrimaryKeySelective(user);
int i=1/0;
return "success";
}catch (Exception e){
throw new Exception(e.getMessage());
}
}
@RequestMapping(value = "/W0003")
@ResponseBody
public String W0003(HttpServletRequest request){
try {
return userService.alterUser();
}catch (Exception e){
return e.getMessage();
}
}
这里继续测试一下,结果如下
看下数据库
发现数据没有被修改,说明回滚成功。
由此可以推知,在spring中如果某个业务方法被一个 整个try catch包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。
不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。