Aop的局限性导致嵌套事务的问题
事情是这样的:
事务都是XML声明拦截 service 包路径下的所有事务
由于这次项目 在service上面直接就是Controller
不想在 Controller 中编写逻辑代码
就想 声明式事务 和 注解事务 同时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class DemoServiceImpl implements IDemoService { public void demo(String msg) { for(xxx in xxx){ try{ this.work(msg); }catch(Exception e){ } } }
@Transactional(propagation = Propagation.REQUIRES_NEW) public void work(String msg) { } }
|
按逻辑应该是没问题的
但是调用之后 并不触发work方法的回滚
原因是:
Spring Aop 代理的是 IDemoService 这个对象 并不是代理方法 通过 IDemoService 注入的Bean
比如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Autowired IDemoService demoService;
demoService.demo();
x 有个 dome方法 x.dome 去调用 DemoServiceImpl.dome 所以 x.dome有被注入事务管理 有被aop切入 而 this.work是 原始方法没有过代理对象所以没有被切入
|
解决方式:
1. AopContext.currentProxy() 获取当前的代理对象 通过代理对象调用 work方法
2. work 写到其他 Service 通过其他Service 调用
原本以为是 Spring 不能同时使用两种代理方式的问题
找了半天 修改了半天配置 结果是AOP代理的局限性导致的问题 捂脸>_<!!!
1 2 3
| TransactionInterceptor interceptor = (TransactionInterceptor) event.getApplicationContext().getBean(TransactionInterceptor.class); interceptor.setTransactionAttributeSources(new AnnotationTransactionAttributeSource(),interceptor.getTransactionAttributeSource());
|
实际上
@ImportResource 的XML中 有填写 tx:annotation-driven 就可以同时使用 两种事务管理方式