Spring事务this自调用的理解误区?真的会让事务失效吗? | 您所在的位置:网站首页 › spring中如何使用事务 › Spring事务this自调用的理解误区?真的会让事务失效吗? |
文章目录
前言this调用是什么this调用事务失效案例this调用事务仍然生效案例?总结
如何解决this调用事务失效
前言
我们经常谈到Spring事务失效会有多种场景导致:可参考我另外一篇文章 一文清晰讲解@Transactional 注解失效场景 @Transactional 应用在非 public 修饰的方法上@Transactional 注解属性 propagation 设置错误@Transactional 注解属性 rollbackFor 设置错误同一个类中方法调用,导致@Transactional失效异常被你的 catch“吃了”导致@Transactional失效数据库引擎不支持事务this自调用这里上面谈到的this自调用真的一定会导致事务失效吗?这就是本文要探索的内容 这种情况就是经典的this自调用导致test2方法的事务失效了! 在Spring框架中,"this"调用通常用于在同一个类的不同方法之间进行方法调用。当一个方法在同一个类中调用另一个方法时,如果使用"this"关键字进行调用,那么该调用将不会经过代理对象,而是直接在当前对象上执行方法。 Spring框架的事务管理是基于代理模式实现的。当一个类被声明为一个事务性Bean时,Spring会使用代理对象来管理该Bean的事务。代理对象会拦截方法调用,并在方法执行前后进行事务管理操作。 然而,当一个方法在同一个类的其他方法中通过"this"关键字进行调用时,调用并不会经过代理对象。这意味着事务管理的切面将无法拦截"this"调用,从而导致事务失效。 this调用事务仍然生效案例?这里说的仍然生效其实是另外一种理解误区,其实本质来说this自调用始终是会导致事务失效的 还是上面的例子改造一下:主要观察test和test2方法上面的注解,这次我们在test方法加上了 @Transactional(rollbackFor = Throwable.class)开启了事务,然后test2方法有几种情况: public void test2()private void test2()加上注解 @Transactional(rollbackFor = Throwable.class,propagation = Propagation.NOT_SUPPORTED) public void test2() @Service public class UserService { @Autowired private MyUserMapper myUserMapper; @Transactional(rollbackFor = Throwable.class) public void test() { User user = new User(); user.setUsername("setUsername"); user.setPassword("setPassword"); myUserMapper.add(user); this.test2(); } //第2种 //private void test2(){...} //第3种 //@Transactional(rollbackFor = Throwable.class,propagation = Propagation.NOT_SUPPORTED) //public void test2(){...} public void test2() { User user = new User(); user.setUsername("setUsername22"); user.setPassword("setPassword22"); myUserMapper.add(user); int i=1/0; user.setUsername("我是修改的数据哦"); myUserMapper.update(user); } }实际运行会发现,上面test2的第3种情况,里面的事务都会进行回滚!!!难道是搞错了? Spring的this自调用不会导致事务失效? 之前我就是一直这样陷入了误区,以为是这样的,其实真实的原因很简单: test() 方法使用了 @Transactional(rollbackFor = Throwable.class) 注解,表明该方法应该在一个事务中执行。当通过 this.test2() 调用 test2() 方法时,它将在当前事务的上下文中被调用!!! 在 Spring 中,默认情况下,@Transactional 注解被设置为 Propagation.REQUIRED,这意味着如果当前已经存在一个事务,那么方法将在该事务中执行;如果没有事务,将创建一个新的事务。因此,在 test() 方法中调用 this.test(),test() 方法将在同一个事务中执行。 总结 所以并不是Spring自调用不会导致事务失效,而是理解问题!test2前两种情况是方法上面根本就没有@Transactional注解,本身就没有事务这一说法,也就不存在所谓的失效、生效了!而第3种情况加上@Transactional(rollbackFor = Throwable.class,propagation = Propagation.NOT_SUPPORTED)想要方法不支持事务,但是发现它还是有事务??所以确实是它注解上的事务失效了(它本质是为了不要事务,但是现在有事务了,所以是失效了)!!然后因为事务传播特性导致它加入了test方法的事务,看起来是事务生效了(反着来,这里好好品味一下) 如何解决this调用事务失效 采用AopContext.currentProxy().方法B名()来进行调用—注意需要在启动类上加一个注解@EnableAspectJAutoProxy(exposeProxy = true)ApplicationContext.getBean()在当前类中注入自己使用手动事务 |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |