最近做项目的时候,订单系统的创建有主订单和若干子订单组成;在开发过程中业务流程是希望主订单和子订单相互不要影响,即主订单操作,不影响子订单操作,这时候就是主订单是一个单独事务,子订单是一个单独事务;
实际代码中,主订单方法增加了
@Transactional(rollbackFor = Exception.class,propagation = PROPAGATION_REQUIRED)
在子订单方法下增加了
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) 一切做好自信运行,在测试时发现问题,子订单事务并没有生效;当时就很奇怪,事物都已经按照相应的增加了,为什么不生效呢?
这时候想到事务本质还是依赖于aop代理的,是不是在代理中出现了问题?
aop代理分为jdk动态代理,cglib动态代理,aop在运行时先获取代理对象,即代理的类对象,然后开启事务,执行前置增强,调用目标对象的目标方法
主订单是使用代理类的目标方法,执行过前置增强,但是在子订单的方法调用中,调用者是主订单方法,并不是代理类对象,没有进行过前置增强,所以子订单事务并没有生效:
在controller层,注入service,service这时候就会有aop代理对象,开启事务的时候进行前置增强;
事务方法中调用子订单,这时候并没有进行aop代理对象开启事务进行前置增强,所以子订单不生效;
明白原因后,在service层自己注入service,在主订单方法中调用子订单时,用注入的service来调用子订单,这时候,注入的service会生成aop代理对象,开启事务进行前置增强,经过测试,子订单事务开始生效:
@Autowired ApplicationContext applicationContext; OrderServiceImpl orderService ; @PostConstruct public void setSelf(OrderServiceImpl orderService){ this.orderService = applicationContext.getBean(OrderServiceImpl.class); }
orderService.subOrder();
到现在问题解决