@Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结 | 您所在的位置:网站首页 › 类的成员函数可以相互调用吗对吗 › @Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结 |
对于方法之间调用,注解@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 实验室设备网 版权所有 |