今天在测试框架的时候,我想在一个service类的方法中调用 当前类的另一个方法(该方法通过@Transactional
开启事务),这时候发现被调用类的事务并没有生效。
public boolean test1() { // xxx 业务逻辑 return test2(); } @Transactional public boolean test2() { testMapper.insertSalary("test", UUID.randomUUID().toString()); int a = 10/0; return true; }
WHY? 搜索引擎一番查询之后,了解到问题的关键:
@Transactional 是基于aop生的代理对象开启事务的
PS:不了解代理模式的小伙伴,结尾有传送门
思路
1.spring 的事务是通过 aop 管理的
2.aop 会通过动态代理 为我们生成代理对象,aop 的功能(例如事务)都是在代理对象中实现的
aop 生成的代理类又在 spring 容器中,所以我们只要在 spring 容器中拿到当前这个bean 再去调用
test2()
就可以开启事务了。
解决
import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;/** * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean * */@Componentpublic class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextHolder.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { assertApplicationContext(); return applicationContext; } @SuppressWarnings("unchecked") public static <T> T getBean(String beanName) { assertApplicationContext(); return (T) applicationContext.getBean(beanName); } public static <T> T getBean(Class<T> requiredType) { assertApplicationContext(); return applicationContext.getBean(requiredType); } private static void assertApplicationContext() { if (SpringContextHolder.applicationContext == null) { throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!"); } } }
public boolean test1() { // xxx 业务逻辑 // 在spring容器中 获取当前类的代理类 return SpringContextHolder.getBean(TestS.class).test2(); } @Transactional public boolean test2() { testMapper.insertSalary("test", UUID.randomUUID().toString()); int a = 10/0; return true; }
作者:殷天文
链接:https://www.jianshu.com/p/cb649e6152b6
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦