java - 如何在Spring的@Transaction层面上对异常进行日志记录?
问题描述
在没使用@Transaction之前,我的业务代码模型大概就是下面这样:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(def);try { studentMapper.insertOnestdent(student); logger.info('Insert one record successfully: ' + student.toString());} catch (Exception ex) { dataSourceTransactionManager.rollback(transactionStatus); // ex.printStackTrace(); logger.error('Insert one record unsuccessfully: ' + student.toString()); return false;}dataSourceTransactionManager.commit(transactionStatus);return true;
类似上面这样的话不管我上面的数据库操作执行成功还是执行失败,我在日志中都可以得到反馈。
但是上面这样的做法,会造成大量的代码的重复,利用spring提供的aop可以实现这样的日志功能,但是后来看文档发现有一个@Transaction注解,使用这个注解,代码可以简化成下面这个样子:
@Transactional(rollbackFor = Exception.class) public boolean insertOneStudent(Student student) {studentMapper.insertOneStudent(student);logger.info('Insert one student successfully' + student.toString());return true; }
这样当数据库操作执行成功的时候我可以日志中成功的进行记录,但是这样的话当插入操作执行失败的时候我应该如何在日志中进行记录。
我现在的初步想法是自己手动实现一个类似@Transaction的动态反射的功能,这样每个要影响数据库中的数据修改的方法执行的时候我都在动态反射的invoke()方法中进行异常的try catch的处理。但是不知道spring是否内置这样的功能?
p.s: 我尽量想将数据库的操作与处理全部放在service层面来处理,不想将日志记录的往上面抛。
问题解答
回答1:insertOneStudent方法整个try catch
try {...} catch (Exception e) { logger.error(e.getMessage(), e); throw e;}
或者实现@RestControllerAdvice,在里面统一打印异常日志像这样:
@RestControllerAdvicepublic class MyExceptionHandler { @ExceptionHandler(value = Exception.class) public Object exceptionHandler(HttpServletRequest request, Exception exception) {logger.warn('异常:', exception);... }}回答2:
spring也有提供切面的异常处理
<!--aop配置 --> <aop:config><!-- 业务类切面 --><aop:pointcut expression='【这里填写切面的匹配规则】' /><!-- 异常处理 --><aop:aspect ref='【处理异常的类ID】'> <aop:after-throwing method='【处理异常的方法名称】' pointcut-ref='【切面ID】' throwing='e' /></aop:aspect> </aop:config>
当然,有xml配置就会有注解配置。主要有下面几个注解
@Aspect 声明切面配置
@Pointcut 声明切面
@AfterThrowing 声明处理方法
注意事项:
处理异常的类是不需要实现任何接口和继承任何类的。
处理异常的方法要声明两个参数(不声明也可以,获取不了异常信息而已),举个例子
public void test(JoinPoint joinPoint, Exception e)
其中joinPoint参数可以获取抛出异常的方法参数信息,Exception对象就不用说了吧。
以上内容仅做参考,spring的版本不同也可能会导致上述说明和实际情况有差异,想获取标准的说明请参阅Spring的官方文档
相关文章:
1. 一个走错路的23岁傻小子的提问2. c++ - win764位环境下,我用GCC为什么指针占8个字节,而long是4个字节?3. angular.js - angularjs 使用鼠标悬停时,标签一直闪4. html5 - HTML代码中的文字乱码是怎么回事?5. javascript - SuperSlide.js火狐不兼容怎么回事呢6. android - 安卓activity无法填充屏幕7. python - django 里自定义的 login 方法,如何使用 login_required()8. node.js - 函数getByName()中如何使得co执行完后才return9. python 计算两个时间相差的分钟数,超过一天时计算不对10. java - 安卓电视盒子取得了root权限但是不能安装第三方应用,请问该怎么办?
