最近自己在写一个aop切面,主要是用来记录日志和打印一些信息的,在测试过程中,发现,业务方法在加了事务之后,如果有其他异常抛出,事务并没有回滚,于是,就Google了一把,发现有大佬遇到过这个问题,大部分博客给到的答案是:因为切面的优先级低于事务的优先级,导致事务advisor生成的代理对象被,切面生成的代理对象给覆盖了,需要在切面上加上@Order(1)注解,这样可以保证,切面的优先级较高
我自己忽然间想到之前,遇到过类似的问题,并且也记录到了线上问题模块,按照实际操作之后,确实:在切面上加了@Order(1)注解之后,事务就生效了
但是自己又想了下,之前学习spring源码的时候,并不记得会生成两个代理对象。。。所以这里就很好奇,所以,自己又撸了一遍aop的源码,最后发现原因了,我的结论是这样的:
  1. 因为我自己写的切面,在@Aroud环绕通知的方法,我手动加了try catch 捕获了throwable 然后打印了一行日志
  2. 在没有加@Order(1)的时候,确实是事务先执行,然后再执行aop的切面,但是在执行切面的时候,捕获到了数组越界的异常,然后打印了日志,没有继续上抛异常
  3. 继而导致事务在处理的时候,并没有捕获到异常,直接就提交事务了, 如果用一段伪代码来描述的话,那应该是这样的

try{
try{
执行目标方法
}catch(th){
log.error(“执行报错”)
}
}catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}

那么问题,就来了,按照我的这个代码,只有在切面中,记录了error日志之后,然后继续抛出异常就可以了,我自己试了下,不在切面上添加@Order(1)注解,也确实是ok的
所以,我写的这个代码,同时开启aop和事务不生效,是因为切面优先级高,先执行,但是把异常给吞掉了,导致事务不知道发生了异常

aop和事务源码

抛开这个问题,那到底会不会生成两个代理对象?我认为是不会生成两个代理对象的,因为我觉得,对于spring来讲,一个bean,既要开启事务,又有切面,如果生成两个代理对象,其实是没必要的,既然切面和事务有优先级,那就嵌套就ok了

在之前博客中,有介绍过springaop和事务的源码,其实,简单来说

  1. 在bean初始化流程中,依次会解析aop的切面和事务advisor
  2. 第八个后置处理器执行的时候,会获取到作用在当前bean的advisor(事务其实就是一个advisor)
  3. 假如此时获取到有两个advisor作用在该bean上,那就根据这两个advisor生成代理对象,在生成代理对象的时候,会专门有一个变量来存储所有的advisor
  4. 在目标方法被执行的时候,会获取方法所要执行的通知方法,按照优先级嵌套执行

所以,我觉得,对于一个问题,要有自己的思考,在解决了问题之后,需要确认下,真正的原因是什么

spring aop和事务同时开启带来的一些问题相关推荐

  1. Spring 如何在一个事务中开启另一个事务?

    Spring项目,需要在一个事务中开启另一个事务. 上面提到的情景可能不常见,但是还是会有的,一旦遇到,如果业务比较复杂,就会很麻烦,但是还是有解决的方案的,比如将一个service方法拆成两个方法, ...

  2. spring aop xml事务配置

    <aop:config> <!-- 通过aop定义事务增强切面--><aop:pointcut id="serviceMethod" expressi ...

  3. Spring AOP及事务说明

    目录 1.事务管理 1.1 事务说明 1.2 Spring事务管理 1.3 事务进阶 (1)Transactional属性说明 (2)rollbackFor属性 (3)propagation属性 1. ...

  4. Spring AOP (事务管理)

    一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...

  5. Spring AOP在事务中的应用典范

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  6. 事务框架之声明事务(自动开启,自动提交,自动回滚)Spring AOP 封装

    利用Spring AOP 封装事务类,自己的在方法前begin 事务,完成后提交事务,有异常回滚事务 比起之前的编程式事务,AOP将事务的开启与提交写在了环绕通知里面,回滚写在异常通知里面,找到指定的 ...

  7. 哪些方法不能够实施Spring AOP事务

    2019独角兽企业重金招聘Python工程师标准>>> 哪些方法不能够实施Spring AOP事务 由于Spring事务管理是基于接口代理或动态字节码技术.通过AOP实施事务增强. ...

  8. 基于Spring中的事务管理机制

    什么是事务? 通俗理解,事务其实就是一系列指令的集合. 为什么要使用事务管理? 我们在实际业务场景中,经常会遇到数据频繁修改读取的问题.在同一时刻,不同的业务逻辑对同一个表数据进行修改,这种冲突很可能 ...

  9. Spring--基于AOP实现事务控制

    Spring–概念与模块 Spring–快速入门 Spring–基于IOC的CRUD操作 Spring–整合Junit Spring–AOP面向切面编程 Spring–基于注解的AOP配置 Sprin ...

  10. Spring AOP简单入门学习

    Spring AOP 1.主要内容: 2.代理模式 ​ 代理模式在 Java 开发中是⼀种⽐较常⻅的设计模式.设计⽬的旨在为服务类与客户类之间插⼊其他功能,插⼊的功能对于调⽤者是透明的,起到伪装控制的 ...

最新文章

  1. 【洛谷P1697】货车运输
  2. 【细无巨细,包你学会】自学Python运行时会遇到的异常与解决方法
  3. 题目梳理(一)(2019.07.06~2019.07.20)
  4. Corosync Pacemaker 高可用 Mariadb
  5. 最后两周!60万奖金AI攻防赛进入冲刺(附baseline代码及实操)
  6. JavaFX逆运动学库2.0
  7. 冒泡排序 自带时间复杂度测试
  8. 前端学习(3167):react-hello-react之鼠标添加一个todoList
  9. 面试题,你什么时候可以入职?回答不好,容易被压薪资
  10. xiao77论坛php,论坛
  11. 【转】linux命令:ifconfig命令
  12. 微信取消支付再二次/多次支付及201商户订单号重复解决思路
  13. C51与MDK共存 Keil5安装教程 WIN10 亲测可用
  14. 熊猫关键词工具v2.8.1.0绿色版SEO工具
  15. PHP获取域名及域名IP的方法
  16. video视频播放中trank标签字幕显示问题
  17. leetcode 803.打砖块(C/C++/Java/python)
  18. 哪里有电,哪里就应该有网络 ,华为移动路由Pro评测
  19. Android破解九宫格密码
  20. 多服务器显卡使用状态监控工具实现

热门文章

  1. PageRank算法简单实现
  2. 容器技术Docker K8s 42 Serverless Kubernetes(ASK)详解-ASK应用管理
  3. 获取最顶层的ViewController top ViewController swift
  4. 易筋SpringBoot 2.1 | 第十一篇:SpringBoot使用actuator
  5. 2021-09-07客户端向 NameNode 请求创建文件,NameNode 根据元数据信息计算出文件的元数 据信息
  6. 295.数据流的中位数
  7. linux常用分区大小,Linux基本知识点总结——硬盘分区及LVM
  8. 深度学习笔记(二):简单神经网络,后向传播算法及实现
  9. 基于IDEA使用Spark API开放Spark程序(1)
  10. 每日一题/006/矩阵/设 n阶实对称矩阵 A满足 A^2=A,且 A 的秩为r,试求行列式 det(2E-A) 的值