「java事务注解失效」事务注解失效原因
本篇文章给大家谈谈java事务注解失效,以及事务注解失效原因对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、事务注解@Transactional不起作用
- 2、你了解的Spring 的 @Transactional 注解控制事务,失效场景知多少?
- 3、你知道@Transactional注解的失效场景吗?
- 4、java让某个注解暂时不生效的方法
- 5、java注解失效?
事务注解@Transactional不起作用
如果Transactional注解应用在非public修饰的方法上,Transactional将会失效。
1》在主方法上,不加@Transactional注解,在子方法上加@Transactional注解,主方法调用子方法,这种情况将会时效
2》在主方法上,加@Transactional注解,子方法上有事务操作,这时候是起作用的。
3》在类上加@Transactional注解,在方法上也加@Transactional注解,方法上的会覆盖类上面的。
在业务方法中一般不需要catch异常,如果非要catch一定要抛出throw new RuntimeException(),或者注解中指定抛异常类型 @Transactional(rollbackFor=Exception.class),否则会导致事务失效,数据commit造成数据不一致,所以有些时候try catch反倒会画蛇添足。
Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。
配置错误导致的,这种情况一般不太会出现
如果出现配置的下面的三种 propagation,事务将不会发生回滚。
ransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
你了解的Spring 的 @Transactional 注解控制事务,失效场景知多少?
这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。
根据 MySQL 的官方文档:
从 MySQL 5.5.5 开始的默认存储引擎是:InnoDB,之前默认的都是:MyISAM,所以这点要值得注意,底层引擎不支持事务再怎么搞都是无济于事。
如下代码所示,当前数据源若没有配置事务管理器,那也是白搭!
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
如果此时把 @Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。
以下引自spring官方文档:
大致意思是:
@Transactional 只能用于 public 的方法上,否则事务会失效。如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
例1:
例1 中,update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务管用吗?
例2:
例2 中,update方法上面加了 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务管用吗?
很遗憾,这两个例子中, updateOrder 方法上的事务都不管用
因为它们发生了自身调用,就是调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效,这也是老生常谈的经典问题了。
6.1这个也是出现比较多的场景:把异常吃了,然后又不抛出来,事务也不会回滚!
6.2
这样事务也是不生效的,因为默认回滚的是:RuntimeException,如果你想触发其他异常的回滚,需要在注解上配置一下,如:
@Transactional(rollbackFor = Exception.class)
这个配置仅限于 Throwable 异常类及其子类。
Propagation.NOT_SUPPORTED:表示不以事务运行,当前若存在事务则挂起。这表示不支持以事务的方式运行,所以即使事务生效也是白搭!
你知道@Transactional注解的失效场景吗?
在使用Spring的时候,进行事务管理变得相当简单:只要在方法上加上 @Transactional 就可以了,Spring就帮我们做了事务的开启、提交和回滚等操作,甚至我一度认为 @Transactional 就是等于Spring事务,只要是见到有数据库操作的方法,默认的统统加上此注解,自以为是的就万事大吉了。你是不是也有与我相同的经历呢:)
其实, @Transactional 也不是在任何的场景下都有效的,有时候会莫名的失效,在介绍之前呢,我们先来认识一下。
1、 @Transactional 注解可以用在哪些地方呢?
作用于类: 表示所有public方法都配置相同的事务信息。
作用于方法: 代表方法的事务信息,其会覆盖类的事务哦!
作用于接口: 这种方法极力不推荐,因为一旦使用cglib,注解会失效。
例如以下示例:
2、 @Transactional 注解还有哪些属性呢?
接下来,我们一起看看 @Transactional 失效的场景。
1、作用在非public方法上会失效
原因是 在使用Spring AOP 代理时,会间接调用AbstractFallbackTransactionAttributeSource的方法computeTransactionAttribute获取事务信息,如果是非public就直接返回了,如下源码:
2、 propagation属性配置错误
TransactionDefinition.PROPAGATION_SUPPORTS:有没有事务无所谓
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:非事务方式执行
TransactionDefinition.PROPAGATION_NEVER:有事务抛异常
3、 rollbackFor设置错误
Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。若需要在特定异常下回滚,则需要指定,比如第一个示例。
4、在同一个类中,方法调用
这个尤其被大家不熟悉,红色标出。
原因是什么,大家可以想一想,我们下一章来分析:)
5、异常被catch给吃掉了
6、数据库底层不支持事务,比如mysql的 myisam引擎。
java让某个注解暂时不生效的方法
java让某个注解暂时不生效的方法的方法是spring关闭expose-proxy这个属性。java是基于spring,expose-proxy实现的注解,一旦关闭expose-proxy,则注解无法生效。
java注解失效?
如果子类要继承父类的注解,那么这个注解必须有 @Inherited 标记。
java事务注解失效的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于事务注解失效原因、java事务注解失效的信息别忘了在本站进行查找喔。
发布于:2022-11-28,除非注明,否则均为
原创文章,转载请注明出处。