Spring service本类中方法调用另一个方法事务不生效问题

一、问题分析
使用AOP 代理后的方法调用执行流程,如图所示
也就是说我们首先调用的是AOP代理对象而不是目标对象,首先执行事务切面,事务切面内部通过TransactionInterceptor环绕增强进行事务的增强,即进入目标方法之前开启事务,退出目标方法时提交/回滚事务。

代码:
问题:
目标对象内部的自我调用将无法实施切面中的增强,如图所示
此处的this指向目标对象,因此调用this.b()将不会执行b事务切面,即不会执行事务增强,因此b方法的事务定义“ @Transactional(propagation = Propagation.REQUIRES_NEW) ”将不会实施,即结果是b和a方法的事务定义是一样的。
二、解决
2.1、说明
此处a方法中调用b方法时,只要通过AOP代理调用b方法即可走事务切面,即可以进行事务增强,如下所示:

判断一个Bean是否是AOP代理对象可以使用如下三种方法:
AopUtils.isAopProxy(bean) : 是否是代理对象;
AopUtils.isCglibProxy(bean) : 是否是CGLIB方式的代理对象;
AopUtils.isJdkDynamicProxy(bean) : 是否是JDK动态代理方式的代理对象;
2.2、 通过ThreadLocal暴露Aop代理对象
1、开启暴露Aop代理到ThreadLocal支持(如下配置方式从spring3开始支持)
<aop:aspectj-autoproxy expose-proxy= "true" /><!—注解风格支持-->
<aop:config expose-proxy= "true" ><!—xml风格支持-->
2、修改我们的业务实现类
this.b();-----------修改为--------->((AService) AopContext.currentProxy()).b();
2.3、代码示例
Service
@Service
public class TbUserServiceImpl extends BaseServiceImpl<TbUserMapper, TbUser> implements TbUserService {

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor=Exception.class)
public boolean modify (Integer id,String name) throws Exception{
TbUser tbUser = new TbUser();
tbUser.setId(id);
tbUser.setName(name);
return mapper.updateByPrimaryKey(tbUser) > 0;
}

@Transactional(rollbackFor=Exception.class)
public boolean login(Integer id,String name) throws Exception{
boolean modify = ((TbUserService) AopContext.currentProxy()).modify(id, name);
System.out.println(1 / 0);
return modify;
}
}

启动类
@SpringBootApplication
@MapperScan("com.liuy.core.mapper")
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@ComponentScan("com.liuy")
public class MysqlApplication {
public static void main(String[] args) {
SpringApplication.run(MysqlApplication.class, args);
}
}

测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class TbUserServiceTest {
@Autowired
private TbUserService tbUserService;

@Test
public void login() throws Exception {
System.out.println("login ==" + tbUserService.login(6, "zhangsan5"));
}
}

测试前数据库:

测试后数据库:

猜你喜欢

转载自blog.csdn.net/qq_18048847/article/details/80476595