关于SpringBoot中事务与异常机制的总结
@Transactional(rollbackFor = Exception.class) public String saveExcel(MultipartFile file) { try { EasyExcel.read(file.getInputStream(), EnrollExcel.class, new MyExcelDataListener<>(new ExcelSaveDataEvent<EnrollExcel>() { @Override public void save(List<EnrollExcel> list) { for (EnrollExcel e : list) { if (e.getRealName() == null || e.getMobile() == null || e.getCourseName() == null || e.getEnrollMode() == null || e.getEnrollTime() == null || e.getIsPay() == null) { throw new RuntimeException("文件中字段为空"); } // String findId = isNew(e.getRealName(), e.getMobile() , null ); StudentDto studentDto = studentDao.findObject(new SQL(){{ SELECT("*"); FROM("sys_user"); WHERE("mobile = '" + e.getMobile() + "' AND user_type = '前端用户' AND sys_name = '投票系统' " ); }}.toString()); if ((ObjectUtil.isEmpty(studentDto))){ throw new RuntimeException("请检查是否有新用户"); } EnrollEntity enrollEntity = new EnrollEntity(); BeanUtils.copyProperties(e, enrollEntity); enrollEntity.setStudentId(studentDto.getId()); String courseName = e.getCourseName(); CourseEntity courseEntity = courseDao.findObject(new SQL() {{ SELECT("*"); FROM("training_course_info i"); WHERE("i.course_name = " + "'" + courseName + "'"); }}.toString()); if(ObjectUtil.isEmpty(courseEntity)){ throw new RuntimeException("课程不存在"); } enrollEntity.setCourseId(courseEntity.getId()); baseDao.insert(enrollEntity); } } })).sheet().doRead(); return "正常"; } catch (RuntimeException e) { log.error("导入Excel出现异常,异常信息,saveExcel : ", e); //捕获到异常后手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return e.getMessage(); } catch (IOException ioException){ log.error("导入Excel出现异常,异常信息,saveExcel : ", ioException); //捕获到异常后手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return "其他异常"; } }
上述需求:在导入Excel的时候检查是否所有必填字段都填了
(1)事务
SpringBoot中采用 @Transactional 设置事务,触发事务的条件,当前方法内出现异常,在上述代码中采用的是 ,throw new RuntimeException(“文件中字段为空”) 的方式,与 throw new Exception() 相比,不需要在方法后面 throws Exception,从而不影响该方法的重写。
(2)异常
异常主要分为 检查性异常 与 运行时异常
检查性异常 :通俗说就是必须被处理的异常,例如 try catch,或者throws (存疑?),如果不进行捕获或者处理,程序将不能被编译,一般是与外部连接而产生的问题,比如 IO找不到文件 , SQL密码或者用户名出错等。
运行时异常:例如 数组越界,被除数为0 等异常,需要修改程序代码来避免。
至于 throw 和 throws 的区别:throw用于程序员手动抛出异常,throws用于声明该方法内抛出了异常
引申出一个两者异常差异而导致的一个小问题:为什么RuntimeException也就是运行时异常不能被throws?
答:对于运行时异常基本上属于代码逻辑上的一个问题,是在编译期间不能预先意料到的异常,即使throws外部调用者也不能处理。
本文作者:YoProgrammer
本文链接:https://www.cnblogs.com/sakanayo/p/16261871.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步