☀️相信在日常开发中,一定经历过这样一个场景,就以下面这段代码抽象一下:
@Service
public class ServiceA {
public void methodA() {
methodB();
methodC();
}
@Transactional
public void methodB() {
// biz..
}
@Cacheable
public void methodC() {
// biz..
}
}
当我们在使用 serviceA.methodA()
的时候,会发现,methodB的事务不生效,methodC的缓存不生效,这就是 Spring 的事务,缓存不生效的经典场景,即同类中的方法调用不生效,而产生这种情况的原因是因为,调用的是同类中的方法,而不是被代理过的方法,因为调用的不是代理的方法,所以不走事务以及缓存的逻辑。
⚡️解決方法1:
既然是同类中的方法引起的,那么就将事务和缓存方法抽离,放到另外一个bean里面进行,这也是较麻烦的。
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
public void methodA() {
serviceB.methodB();
serviceB.methodC();
}
}
@Service
public class ServiceB {
@Transactional
public void methodB() {
// biz..
}
@Cacheable
public void methodC() {
// biz..
}
}
⚡️解决方法2:
既然是没走代理的方法,那么让他调用代理的对象的代理方法即可
@Service
public class ServiceA {
@Autowired
private ServiceA serviceA;
public void methodA() {
serviceA.methodB();
serviceA.methodC();
}
@Transactional
public void methodB() {
// biz..
}
@Cacheable
public void methodC() {
// biz..
}
}
⚡️解决方法3:
通过一些Spring对象的容器工具,一般是已经被封装过的,通过静态方法来获取Bean对象(绕过了自己调用自己),再通过Bean对象来直接调用方法,这样就会走代理,所以这也是比较优雅的。
@Service
public class ServiceA {
public void methodA() {
SpringUtil.getBean(ServiceA.class).methodB();
SpringUtil.getBean(ServiceA.class).methodC();
}
@Transactional
public void methodB() {
// biz..
}
@Cacheable
public void methodC() {
// biz..
}
}