一、Spring Boot 事务支持
在使用Jdbc 作为数据库访问技术时,Spring Boot框架定义了基于jdbc的PlatformTransactionManager接口的实现DataSourceTransactionManager,并在Spring Boot应用启动时自动进行配置。如果使用jpa的话Spring Boot同样提供了对应实现。
数据访问技术 | 实现 |
---|---|
JDBC | DataSourceTransactionManager |
JPA | JpaTransactionManager |
Hibernatc | HibernateTransactionManager |
JDO | JdoTransactionManager |
分布式事务 | JtaTransactionManager |
这里Spring Boot集成了mybatis框架,mybatis 底层数据访问层实现基于jdbc 来实现,所以在Spring Boot环境下对事务进行控制,事务实现由Spring Boot实现并自动配置,在使用时通过注解方式标注相关方法加入事务控制即可。
申明式事务配置
//事务管理
@Transactional(propagation = Propagation.REQUIRED)
public void addUser(User user){
//判断字符串是否为空
//StringUtils.isBlank(str);
//判断用户名是否为空
AssertUtils.isTrue(StringUtils.isBlank(user.getUsername()),"用户名不能为空");
//判断手机号是否为空
AssertUtils.isTrue(StringUtils.isBlank(user.getUserphone()),"电话号不能为空");
//判断用户名是否存在
User query = userMapper.Query(user.getUsername());
AssertUtils.isTrue(query != null,"用户名已存在,请重试");
//执行添加操作,判断受影响行数
AssertUtils.isTrue(userMapper.addUser(user) > 1,"添加用户失败!");
}
二、Spring Boot 全局异常处理
SpringMvc中对异常统一处理提供 了相应处理方式,推荐大家使用的是实现接口HandlerExceptionResolver的方式,对代码侵入性较小。
在Spring Boot应用中同样提供了对异常的全局性处理,相关注解如下:
1、@ControllerAdvice
该注解组合了@Component注解功能,最常用的就是作为全局异常处理的切面类,同时通过该注解可以指定包扫描的范围。@ControllerAdvice约定了几种可行的返回值,如果是直接返回model类的话,需要使用@ResponseBody进行json传涣
2、@ExceptionHandler
该注解在Spring 3.X版本引入,在处理异常时标注在方法级别,代表当前方法处理的异常类型有哪些具体应用以Restful接口为例,测试保存用户接口。
3、全局异常应用
3.1 异常抛出与全局异常捕获
- UserController 查询接⼝
@ApiOperation(value = "根据⽤户id查询⽤户记录")
@ApiImplicitParam(name = "userId",value = "⽤户ID",required = true, paramType = "path")
@GetMapping("user/id/{userId}")
public User queryUserByUserId(@PathVariable Integer userId){
return userService.queryUserByUserId(userId);
}
- UserService 查询业务⽅法,抛出 ParamExceptions 异常
public User queryUserByUserId(Integer userId){
// 抛出异常
AssertUtil.isTrue(true,"异常测试...");
return userMapper.queryById(userId);
}
- 全局异常处理类 GlobalExceptionHandler 定义
@ControllerAdvice
public class GlobalExceptionHandler{
/**
* 全局异常处理 返回json
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultInfo exceptionHandler(Exception e){
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(300);
resultInfo.setMsg("操作失败!");
if(e instanceof ParamsException){
ParamsException pe = (ParamsException) e;
resultInfo.setMsg(pe.getMsg());
resultInfo.setCode(pe.getCode());
}
return resultInfo;
}
}
- Postman 执⾏测试效果
3.2 特定异常处理
- 通过 @ExceptionHandler 标注⽅法处理特定异常,这⾥以⽤户未登录异常为例,通过全局异常进⾏统⼀处理
/**
* ⽤户未登录异常特殊处理 返回json
* @param authExceptions
* @return
*/
@ExceptionHandler(value = NoLoginException.class)
@ResponseBody
public ResultInfo userNotLoginHandler(NoLoginException authExceptions){
System.out.println("⽤户未登录异常处理。。。");
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(authExceptions.getCode());
resultInfo.setMsg(authExceptions.getMsg());
return resultInfo;
}
- 在⽤户修改接⼝中抛出未登录异常为例进⾏测试
/**
* 修改⽤户
* @param user
* @return
*/
@ApiOperation(value = "更新⽤户")
@ApiImplicitParam(name = "user", value = "⽤户对象")
@PostMapping("/user")
public ResultInfo updateUser(@RequestBody User user) {
if(1 == 1){
throw new NoLoginException();
}
ResultInfo resultInfo = new ResultInfo();
userService.updateUser(user);
return resultInfo;
}
- Postman 执⾏测试效果