@Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结 您所在的位置:网站首页 类的成员函数可以相互调用吗对吗 @Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结

@Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结

2024-02-20 02:30| 来源: 网络整理| 查看: 265

对于方法之间调用,注解@Transaction生效以及失效的场景

首先,我们需要知道,Spring是通过代理管理事务的,方法和方法之间的调用分为两种情况(解决办法可在下面列举的不同场景中自取):

1.不同类之间的方法调用。如类A的方法a()调用类B的方法b(),这种情况事务是正常起作用的。只要方法a()或b()配置了事务,运行中就会产生代理,开启事务。

注意,事务正常起作用是指注解的方法内事务操作生效,下面是两种典型场景实例:

如果是在A的方法a()上加@Transactional注解,那么先正常调用b()且b()有增删改操作,但是接着执行a()的动库操作异常,则两个方法内动库操作全部回滚;

如果A的方法a()没加@Transactional注解,而类B的方法b()上加了该注解,那么如果先正常执行中a()的动库操作,然后执行类B的方法b()的动库操作发生异常,那么b()中的事务操作会全部回滚,但是并不会影响先前a()中的操作,即b()中异常b()回滚,a()不回滚。

2.同一个类的不同方法之间的调用。以同类中方法a()调用方法b()为例:

1).方法a()开启了事务,事务正常生效

2).方法a()没有开启事务,此时调用方法b(),无论被调用的b()是否配置了事务,事务都不会生效

说明:在微服务架构中,很多方法里面会有各种跨库跨服务器操作,这时候你添加注解@Transactional就不会使事务生效了,我们会寻求Seata等其他技术方案解决分布式事务问题。

其他使用@Transactional注解失效的场景,需要注意:

1.方法是非public,其事务就会失效:

该注解一般标注在类或者public方法上,如果方法是非public,其事务就会失效

2.@Transactional 注解属性 propagation 设置错误

如果设置的事务传播行为是这三种,发生错误事务将不会回滚:

TransactionDefinition.PROPAGATION_SUPPORTS

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

TransactionDefinition.PROPAGATION_NEVER

3.try catch内部消化了:

如果在该注解标注的方法或被其调用的方法中有try catch,那么想要使得事务生效,一定要在catch中把异常直接抛出,如果不处理不向上抛出,则事务不会生效。

4.没有设置属性rollbackFor = Exception.class :

@Transactional只能回滚RuntimeException和RuntimeException下面的子类抛出的异常 不能回滚Exception异常!!!如果需要支持回滚Exception异常请用@Transactional(rollbackFor = Exception.class),如果是增删改的时候我建议大家都使用@Transactional(rollbackFor = Exception.class)。

5.数据库引擎不支持事务

常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有