文章
问答
冒泡
spring 工程中处理 同一个类中调用aop的对象

在使用spring作为开发框架的时候,大家经常会遇到一个情况,在同一个类中,a函数去调用一个加了事务注解的b函数,这个时候,b函数上的事务是不生效的。
至于原因,相信大家都是知道的,就是因为这个时候,a调用b的时候,没有走代理类。

而要生效的话,我们需要去得到他的代理对象


总的来说,实现方案,就是不能让他直接内部调用,需要走代理对象去执行
具体实现方法
1.通过Lazy,把当前bean注入给自己

@Service
public class UserService {

    @Autowired
    @Lazy
    private UserService self;

    public void upsert(){
        self.create(new User());
    }


    @Transactional
    public void create(User user){
        System.out.println("[UserService] create user");
    }
}


开启debug日志级别,执行测试方法

@Test
public void upsert(){
    userService.upsert();
}

 

2022-01-10 14:16:15.924 DEBUG 32298 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Creating new transaction with name [com.moensun.springboot2.mvc.service.UserService.create]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-01-10 14:16:15.928 DEBUG 32298 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@3caf5c96] for JDBC transaction
2022-01-10 14:16:15.931 DEBUG 32298 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@3caf5c96] to manual commit
[UserService] create user
2022-01-10 14:16:15.949 DEBUG 32298 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Initiating transaction commit


事务生效

2.暴露aopContext,通过aopContext获取代理对象
开启配置

@EnableAspectJAutoProxy(proxyTargetClass = true,exposeProxy = true)
@Service
public class UserService {

    @Autowired
    private UserService self;

    public UserService getSelf() {
        return (UserService) AopContext.currentProxy();
    }

    public void upsert(){
        self.create(new User());
    }

    @Transactional
    public void create(User user){
        System.out.println("[UserService] create user");
    }
}

 

2022-01-10 14:23:01.733 DEBUG 32368 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Creating new transaction with name [com.moensun.springboot2.mvc.service.UserService.create]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2022-01-10 14:23:01.737 DEBUG 32368 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@78d6c244] for JDBC transaction
2022-01-10 14:23:01.740 DEBUG 32368 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@78d6c244] to manual commit
[UserService] create user
2022-01-10 14:23:01.759 DEBUG 32368 --- [           main] o.s.jdbc.support.JdbcTransactionManager  : Initiating transaction commit


事务生效

当然还有其他的解决方案,比如不用动态代理,用静态代理。或者是直接编程式事务。这里我们解决的是这种基于注解的切面问题。不局限于@Transactional。上面的两种方式,都可以达到效果,但是,相对来说第二种方式,更加推荐一点,比较符合spring的思想。

spring
aop

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读