spring使用事务的注意事项
Q1.同一个类中事务方法是无法直接调用的,如果 ServiceA.methodA调用 Service.methodB,会使被调用方法的事务失效。
因为spring的事务是基于代理类来实现的。在controller里的service其实是代理对象,所以b方法的事务有效。,而在同一个类中ServiceA.methodA调用 Service.methodB,你拿到的不是代理后的methodB,所以事务会失效
解决方法很简单,在methodA方法类中获取当前对象的代理对象
ServiceA proxy =(ServiceA)AopContext.currentProxy();
proxy.b();
Q2.“Transaction rolled back because it has been marked as rollback-only ”异常的出现。
出现场景:这种异常一般是在,嵌套事务使用中,内层事务使用默认的事务传播行为(Propagation.REQUIRED),内外共用一个事务时,外层方法把内层方法try catch 住了,就会出现。
原因:内层方法出异常了,会向上抛异常,SpringAOP拦截到,就会把事务标志为rollback only,就是准备要回滚。
由于内外方法共用一个事务,这时要是外层方法把这个异常捕获了,外层方法就继续提交。但是事务标记已经置了,那就会抛这个异常。
Q3.由于在一个事务里,事务还未提交,导致某些操作变更数据未生效。
出现场景:存在一个方法A,里面的执行逻辑是先对表A增加/更新一些数据,然后又执行了查询操作,发现未查询到之前的变更数据。
解决办法:将两个操作放在不同的事务里。