SpringAOP同类调用失效(事务失效)

项目场景:

同一个 ServiceA 中有B()方法、C()方法,在 ServiceA 中B()调用C()时,事务注解@Transactional不生效


@Service
public class ServiceA {
    public void B(){
    	//...
    	C();
    }
    
	@Transactional(rollbackFor = Exception.class)
	public void C(){
    	//...
    }
}

原因分析:

Spring基于AOP机制实现事务的管理,@Authwired 这样的方式当调用方法时实际上是通过Service代理类调用了目标方法,代理类在执行目标方法前后,做了事务管理的相关操作 ,而同类中的调用是this表示的是当前的对象,而不是代理对象导致事务失效。


解决方案:

这里有三种方式:

1.自己注入自己

spring通过三级缓存解决了循环依赖的问题,所以自己注入自己的写法不会有循环依赖问题,但是如果C()方法上还有注解 @Async 会报循环依赖错误,该方法就不可取。

@Service
public class ServiceA {

	@Autowired
	ServiceA serviceA;
	
    public void B(){
    	//...
    	serviceA.C();
    }
    
	@Transactional(rollbackFor = Exception.class)
	public void C(){
    	//...
    }
}

2.使用AopContex

使用AopContext获取到当前代理类,还需在启动类加上注解@EnableAspectJAutoProxy(exposeProxy = true) 否则会报错

@Service
public class ServiceA {

    public void B(){
    	//...
    	((ServiceA) AopContext.currentProxy()).C();
    }
    
	@Transactional(rollbackFor = Exception.class)
	public void C(){
    	//...
    }
}
@EnableAspectJAutoProxy(exposeProxy=true)
public class ServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServerApplication .class, args);
    }
}

当然这种这种方式不能保证一定有效,当使用@Async在入口方法B()方法上时会报错。

3.使用Spring上下文ApplicationContext

创建工具类:SpringBeanUtil

@Component
public class SpringBeanUtil implements ApplicationContextAware {
 
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
 
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
}
@Service
public class ServiceA {

    public void B(){
    	//...
    	ServiceA bean = SpringBeanUtil.getBean(ServiceA .class);
        if (null != bean) {
            bean.C();
        }
    }
    
	@Transactional(rollbackFor = Exception.class)
	public void C(){
    	//...
    }
}

你可能感兴趣的:(spring)