首页 > 其他分享 >同一个类调方法导致注解式事务失效的问题

同一个类调方法导致注解式事务失效的问题

时间:2023-09-22 15:26:32浏览次数:51  
标签:对象 Spring 使用 代理 默认 类调 AOP 注解 失效

说明

在项目启动时,如果有@Transactional注解,spring是生成代理类来开启事务、提交事务和回滚事务的,但是如果是同一个类之间调用,就是直接调方法,导致事务失效。我们可以用一下方式在同一类获取当前类的代理对象,从而避免事务失效的问题。但是这种方式会有问题,下面有说明。推荐调用拆到两个类中

代码

  • 在启动类开启
@EnableAspectJAutoProxy(exposeProxy = true)
  • 使用
    handle()上有@Transactional事务注解
AService aService = (AService ) AopContext.currentProxy();
WebResult webResult = aService.handle();

使用上述方法需要注意的点

  • 需要确保当前方法是通过代理对象调用的,而不是直接通过类的实例调用的。否则,AopContext.currentProxy()将返回null。
  • 需要在Spring容器中开启了exposeProxy配置,即在@EnableAspectJAutoProxy注解中设置exposeProxy属性为true。否则,AopContext.currentProxy()将返回null。
  • 需要注意潜在的性能影响。每次调用AopContext.currentProxy()都会涉及到AOP拦截器链的处理,可能会对性能产生一定的影响。因此,建议在必要的情况下使用,并进行性能测试和评估。

总之,使用AopContext.currentProxy()可以解决同一个类调用方法导致注解式事务失效的问题,但需要注意上述提到的使用条件和潜在的性能影响及可能会破坏Spring AOP的默认行为。

破坏的Spring AOP的默认行为

破坏Spring AOP的默认行为主要包含以下几种方式:

  1. 强制使用CGLIB代理:在Spring AOP中,默认情况下,如果被代理的对象没有实现接口,会使用CGLIB来创建代理对象。但是,如果你强制使用CGLIB代理,即使被代理的对象已经实现了接口,也会使用CGLIB来创建代理对象,破坏了Spring AOP的默认行为。
  2. 修改默认的代理实现方式:在Spring Boot 2.x中,AOP默认使用CGLIB实现,而在Spring 5.x中,AOP默认使用JDK动态代理。如果你通过配置项spring.aop.proxy-target-class=false来修改默认的代理实现方式,即使是在Spring Boot 2.x中,也会使用JDK动态代理来创建代理对象,破坏了Spring AOP的默认行为。
  3. 使用AspectJ织入:Spring AOP默认使用基于代理的AOP实现,即Spring会创建一个代理对象,然后将该代理对象织入到目标对象中。如果你使用AspectJ织入,Spring会创建一个Aspect对象,然后将该Aspect对象织入到目标对象中,破坏了Spring AOP的默认行为。

需要注意的是,这些行为并不一定都是负面的。它们有可能帮助解决某些特定的问题。但是,在破坏Spring AOP默认行为之前,一定要考虑清楚是否真的需要这样做,以及可能的副作用是什么。

标签:对象,Spring,使用,代理,默认,类调,AOP,注解,失效
From: https://www.cnblogs.com/shareToAll/p/17722433.html

相关文章

  • Spring 02 Spring注解开发
     dao层publicinterfaceUserDao{voidinsertUser();}实现类/*@Component(value="userDao")配置到实例里去或者直接用下面的Repository*/@Repository("userDao")publicclassUserDaoImplimplementsUserDao{@OverridepublicvoidinsertUser(......
  • 慢SQL原因分析之索引失效
    现象最近收到一个慢sql工单,慢sql大概是这样:“selectxxxfromtabelwheretype=1”。咦,type字段明明有索引啊,为啥是慢sql呢?原因通过执行explain,发现实际上数据库执行了全表扫描,从而被系统判定为慢sql。这时有一定开发经验的同事会说:“字段区分度不够,这种字段作单独索引是......
  • 对某个接口进行限流 以 Aop 注解的形式绑定接口 用redis实现
    简单的针对某个接口进行限流,如果需要整体限流的话还是建议在网关上面或者服务器上面动手Controller:@LimitRequest(count=1,time=60*1000*2)@PostMapping("limit")publicStringgetLimitResult(){return"ok";}Annotation:@Retention(R......
  • SpringBoot2集成RabbitMQ(注解+回调)
    一、概述RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。RabbitMQ主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中......
  • 注解解析的BeanDefinition
    配置文件解析完后,剩下的工作就是注册了,是processBeanDefinition函数中的BeanDefinitionReaderUtils.registerBeanDefinition(bdHodler,getReaderContext().getRegistry())代码的解析了。publicstaticvoidregistryBeanDefinition(BeanDefinitionHolderdefinitionHolder,BeanDefi......
  • Mybatis 05 注解实现增删改查
    UserMapperpublicinterfaceUserMapper{/*注解实现增删改查*/@Select("select*fromtb_user")List<User>selectAll2();@Insert("insertintotb_uservalues(null,#{username},#{password},#{gender},#{addr})")voidinsert......
  • Spring注解工具类
    前言在看Spring源码的时候,经常会有处理注解的时候,比如从方法上获取注解,类上获取注解,注解属性别名。JDK中自带的获取注解API有点简单,不会从父类方法或者接口上的方法去查找,不能为属性定义别名等,因此Spring封装了一个便利的工具类,更加方便的去获取注解信息。JDK自带方法Annotated......
  • 详解Spring缓存注解@Cacheable、@CachePut和@CacheEvict
    详解Spring缓存注解@Cacheable、@CachePut和@CacheEvict的使用简介在大型的应用程序中,缓存是一项关键技术,用于提高系统的性能和响应速度。Spring框架提供了强大的缓存功能,通过使用缓存注解可以轻松地集成缓存机制到应用程序中。本文将详细介绍Spring框架中的@Cacheable、@CachePu......
  • 主动写入流对@ResponseBody注解的影响
    问题回溯2023年Q2某日运营反馈一个问题,商品系统商家中心某批量工具模板无法下载,导致功能无法使用(因为模板是动态变化的)商家中心报错(JSON串):{"code":-1,"msg":"失败"}负责的同事看到失败后立即与我展开讨论(因为不是关键业务,所以不需要回滚,修复即可),我们发现新功能模板下载的代码......
  • 主动写入流对@ResponseBody注解的影响 | 京东云技术团队
    问题回溯2023年Q2某日运营反馈一个问题,商品系统商家中心某批量工具模板无法下载,导致功能无法使用(因为模板是动态变化的)商家中心报错(JSON串):{"code":-1,"msg":"失败"}负责的同事看到失败后立即与我展开讨论(因为不是关键业务,所以不需要回滚,修复即可),我们发现新功能模板下载的代码与之前......