最近在作事务添加时 发现本身的事务没有新建,上网查到 仅用做收藏。spring
其二 注意 事务的注解 应该在 内层的事务上面.net
1、描述
Spring遇到嵌套事务时,当被嵌套的事务被定义为“PROPAGATION_REQUIRES_NEW”时,
内层Service的方法被调用时,外层方法的事务被挂起;
内层事务相对于外层事务是彻底独立的,有独立的隔离性等等。
2、实验
但实验时却遇到一个奇怪的问题:
一、当ServiceA.a()方法调用ServiceB.b()方法时,内层事务提交和回滚,都不受外层事务提交或回滚的影响。
二、当ServiceA.a()方法调用ServiceA.c()方法时,内层事务不能正确地提交或回滚。
3、演示代码
XXXService中,有下面两个方法:
@Transactional
method_One() {
method_Two();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
method_Two(){
//do something
}
4、分析和结论
一、method_Two()会不会建立一个新事务?
答:不会建立。仔细查看了日志,没有找到相似creating new transaction的输出,应该是由于在同一个Service类中,spring并不从新建立新事务,若是是两不一样的Service,就会建立新事务了。
那么为何spring只对跨Service的方法才生效?
Debug代码发现跨Service调用方法时,都会通过org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept()方法,只有通过此处,才能对事务进行控制。
二、不一样的Service调用方法时:
若是被调用方法是Propagation.REQUIRES_NEW,被catch后不抛出,事务能够正常提交;
若是被调用方法是Propagation.REQUIRED,被catch后不抛出,后面的代码虽然能够执行下去,但最终仍是会分出rollback-only异常;
三、同一个Service中调用方法时:
不论注解是Propagation.REQUIRES_NEW 仍是 Propagation.REQUIRED,
其结果都是同样的,就是都被忽略掉了,等于没写。
当其抛出异常时,只需catch住不抛出,事务就能够正常提交。
日志
参考 http://blog.csdn.NET/chs_jdmdr/article/details/46411879blog