bService.b()方法使用默认的传播行为REQUIRED,和a共用一个事务, int i =10/0;出现异常需要回滚,b会回滚。 bService.c()方法使用默认的传播行为REQUIRES_NEW,和a不共用一个事务, int i =10/0;出现异常需要回滚,b会回滚。
结论:bService.b()回滚,bService.c()不回滚。的写法和下面的写法一模一样:
class AServiceImpl{ @Transactional public void a() { System.out.println("b"); System.out.println("c"); } }即b和c自己的事务失效,完全相当于拷贝代码到a方法中。如果我们想要的是各自拥有自己的自治的事务,该怎么办呢?为什么会出现这个问题?
原因:@Transactional 底层使用的是aop,使用的代理对象才能使用事务,本方法内部嗲用,绕过了代理对象,所以bc事务无效,a仍然有效(如果其类通过代理对象调用的话)。
1.先引入aspactj的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 在嗲用b,c方法之前通过切面重新获得此对象的代理AServiceImpl aService = AopContext.currentProxy(); 可以解决这个问题。 代码如下: class AServiceImpl{ @Transactional public void a() { AServiceImpl aService = AopContext.currentProxy(); aService.b(); aService.c(); } @Transactional(propagation = Propagation.REQUIRED,timeout = 2) public void b() { System.out.println("b"); } @Transactional(propagation = Propagation.REQUIRES_NEW,timeout = 2) public void c() { System.out.println("c"); } }另外在抽象出一层,做事务层,不要把相互调用的方法放到一类中
这种会造成循环依赖,会爆炸:
@AutoWide AServiceImpl AServiceImpl; 前路无畏 认证博客专家 专家认证 自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!自律的艰辛总甜过懊悔的苦果!专注于java后端技术及解决方案,善于总结,分享!