Spring事务控制是通过AOP的方式实现的,那也就是说必须通过了这个切面才会有事务的代理(从spring的context去取一个bean时)。
例子1:
事务切面配置在service层
ServiceA中有两个方法a和b
方法a配置为REQUIRED
方法b配置为REQUIRES_NEW
在ServiceA中的a方法调用b方法,这个时候b的REQUIRES_NEW是不起作用的,因为外围调用了ServiceA的a方法,通过了切面,事务配置了REQUIRED。在方法a里面调用b方法,这个时候并没有通过切面,因此方法b的REQUIRES_NEW就不起作用了。
如果在ServiceB中的方法调用ServiceA中的方法b,这个时候通过了前面,因此方法b的REQUIRES_NEW就起作用了。
同理例子2:
使用JTA事务
事务切面配置在service层
ServiceA中有方法a和方法b
ServiceB中有方法c
配置Exception1为rollback-for
如果ServiceA中的方法a调用ServiceB中的方法c,方法c中抛出Exception1,方法a截获并不抛出,但最后事务提交时候还是会rollback。因为调用方法c的时候通过了切面,这个时候JTA事务起了作用,c抛出Excepion1,整个事务就标记为rollback,这个时候不管方法a时候catch住,事务都会rollback。
同样ServiceA中的方法a调用ServiceA中的方法b,方法b中抛出Exception1,方法a截获并不抛出,最后事务是可以提交的。因为调用方法b的时候是在同一个service中并没有通过切面。throws
因此在一个大型的项目中,一开始就要为之后的开发设置好合理的切面,哪些Exception需要roolback,哪些Exception不需要rollback。
在最近的开发中发现了,Service层的接口还是需要throws特定的Exception的。
情况:
整个公司产品的切面是切在 test.*Service下的所有方法的,并试用JTA事务。一个team开发了一个接口AService中有个方法a,但并没有throws Exception,其他模块要调用这个接口,如果想要在AService的方法a抛出unCheckedException的时候并不打断外围逻辑的执行(外面的事务并不回滚)。因为接口并没有throws 特定Exception,而是会抛出unCheckedException,这个时候就没有办法配置no-rollback-for了。

没有评论:
发表评论