针对spring事务内部调用失效处理方式:
spring事务失效场景详见:https://mp.csdn.net/mp_blog/creation/editor/131274984
同一个service类中,主方法没有加事务,则该方法调用内部增加注解的方法时,事务不会生效。
原理:
@Transactional基于AOP实现,而AOP又是基于动态代理实现,直接调用本类方法或使用this调用本类方法,均不是Spring的代理对象,无法实现动态代理,事务也就不会生效。
解决方法:
方法一、将方法合成一个方法。
方法二、将被调用方法放入另一个被Spring管理的类中,用实例对象调用。
方法三、用@Autowired在本类中注入当前实例,通过实例调用该方法。
方法四、用@Autowired在本类中注入ApplicationContext示例,在调用的地方使用applicationContext.getBean(this.getClass());获取当前实例即可。
@Autowired
private ApplicationContext applicationContext;
applicationContext.getBean(this.getClass());
方法五、使用SpringUtils工具类,实现BeanFactoryPostProcessor
在方法调用处使用SpringUtils.getBean()方法获取实例。
@Component
public class SpringUtils implements BeanFactoryPostProcessor {
/**
* Spring应用上下文环境
*/
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
T result = (T) beanFactory.getBean(clz);
return result;
}
}
IUserInfoService userInfoService = SpringUtils.getBean(IUserInfoService.class);