@Transactional 注解失效场景
@Transactional可以用在接口、类、类方法上。
作用于类:当把@Transactional注解放在类上时,表示该类的所有public方法都配置了该事物注解。
作用于方法:表示该方法配置了事物注解,当类配置了@Transactional注解,方法上也配置了@Transactional注解,方法的事物会覆盖类的事物配置。
作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring Aop使用CGLIB动态代理,将会导致@Transactional注解失效。
失效场景:
一、@Transactional应用在非public修饰的方法上
只所以会失效是因为Spring Aop代理时,TransactionInterceptor (事务拦截器)会在目标方法执行前后进行拦截,
DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy 的 invoke方法会间接调用 AbstractFallbackTransactionAttributeSource 的 computeTransactionAttribute方法,
获取Transactional 注解的事务配置信息。
此方法会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。
注:protected、private 修饰的方法上使用 @Transactional 注解,虽然事务无效,但不会有任何报错,这是我们很容犯错的一点。
二、@Transactional注解属性propagation设置错误
这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
propagation代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:
① Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。
( 也就是说如果A方法和B方法都添加了注解,在默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 )
② Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
③ Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
④ Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。
( 当类A中的 a 方法用默认Propagation.REQUIRED模式,类B中的 b方法加上采用 Propagation.REQUIRES_NEW模式,
然后在 a 方法中调用 b方法操作数据库,然而 a方法抛出异常后,b方法并没有进行回滚,因为Propagation.REQUIRES_NEW会暂停 a方法的事务 )
⑤ Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。
⑥ Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。
⑦ Propagation.NESTED :和 Propagation.REQUIRED 效果一样。
三、@Transactional注解属性rollbackFor设置错误
rollbackFor 可以指定能够触发事务回滚的异常类型。
Spring默认抛出了未检查unchecked异常(继承自 RuntimeException的异常)或者 Error才回滚事务;
其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。
四、同一个类中方法调用,导致@Transactional失效
开发中避免不了会对同一个类里面的方法调用,
比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。
则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。
五、异常被catch“吃了”,导致@Transactional失效
spring的事务是在调用业务方法之前开始的,业务方法执行完毕之后才执行commit or rollback,
事务是否执行取决于是否抛出runtime异常。如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
在业务方法中一般不需要catch异常,如果非要catch一定要抛出throw new RuntimeException(),
或者注解中指定抛异常类型@Transactional(rollbackFor=Exception.class),否则会导致事务失效,数据commit造成数据不一致,所以有些时候try catch反倒会画蛇添足。
六、数据库引擎不支持事物
这种情况出现的概率并不高,事务能否生效数据库引擎是否支持事务是关键。
常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了。
@Transactional 注解失效场景的更多相关文章
- Spring中@Translational注解失效场景
今天面试被问到@Translational注解什么场景下失效,我一脸懵逼,说的恍恍惚惚的,下来我就总结一下@Translational注解失效的场景! @Transactional 注解相信大家并不陌 ...
- @Transactional注解失效的解决方案
一.前言 开发中我们经常使用 @Transactional注解来启用Spring事务管理,但是如果使用方法不当,会遇到注解不生效该事务回滚的地方却没有回滚的问题. 总结下一般是以下几个原因: @Tra ...
- 聊聊@Transactional 的失效场景,有哪些坑?
先别急着回答,看完再说也不迟嘛.我们都知道在 Spring 项目中,我们可以直接使用注解 @Transactional 来标识一个事务方法.然而,你可能并不知道这个事务是不是按照你想的方式执行.下面我 ...
- @Transactional注解失效
一.特性 先来了解一下@Transactional注解事务的特性吧,可以更好排查问题 1.service类标签(一般不建议在接口上)上添加@Transactional,可以将整个类纳入spring事务 ...
- 一口气说出 6种,@Transactional注解的失效场景
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...
- @Transactional注解的失效场景
一口气说出 6种,@Transactional注解的失效场景 计算机java编程 发布时间: 20-03-1912:35优质科技领域创作者 引言 昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Tr ...
- @Transaction注解失效的几种场景
一.@Transactional介绍 1.@Transactional注解可以作用于哪些地方? @Transactional 可以作用在接口.类.类方法上. 作用于类:表示所有该类的public方法都 ...
- Spring @Transactional注解不起作用解决办法及原理分析
Transactional失效场景介绍 第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用.例如以下代码. 定义一个错误的@Trans ...
- spring事务注解失效问题
问题描述: 由于工作需要,需要在spring中配置两个数据源,有一天突然发现@Transactional注解失效 环境框架: springmvc+spring+spring jdbcTemplate ...
随机推荐
- Spring Cloud Alibaba系列(二)nacos作为服务配置中心
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...
- 记一次jackson序列化Boolean的坑
@Data public class CouponTemplateDto { /** * 优惠券类型id */ private Long couponTypeId; /** * 优惠券模板id */ ...
- 仿站-获取网站的所有iconfont图标
在仿站过程中,网站的iconfont查找非常浪费时间,这里教大家一次性获取网站iconfont的方法 1.打开 开发者工具 在element中搜索font-face,结果如下,复制font-face所 ...
- 记一次 spinor flash 读速度优化
背景 某个项目使用的介质是 spinor, 其 bootloader 需要从 flash 中加载 os. 启动速度是一个关键指标,需要深入优化.其他部分的优化暂且略过,此篇主要记录对 nor 读速度的 ...
- 一文教你快速搞懂 FOC ramp function 斜坡函数的作用和实现
文章目录 定义 程序的实现 matlab 程序 C语言程序 定义 x(t)={0,t<0At,t≥0 x(t) = \begin{cases} 0,t<0\\ At,t \ge 0\\ \ ...
- 小程序如何动态修改标题navigationBarTitleText
首先我们先设置标题.进入页面所在的json文件加入以下代码即可成功设置: "navigationBarTitleText": "我是标题啊!", 然后修改这个标 ...
- 目前校园百晓生APP与CSDN软件的对比
不忘初心.注入灵魂 设计之初 在做校园百晓生该APP时,初心是为校园的同学提供便捷的查询校园信息的服务,确实目前的软件已经实现了该功能,但是总感觉缺少一些灵魂,感觉大部分人渴望的重点在于信息而不是自己 ...
- 设计模式之GOF23工厂模式02
抽象工厂模式 不能添加单个产品,产品族 public interface Seat { void anmo();}class GoodSeat implements Seat { @Override ...
- java中"no enclosing instance of type * is accessible"的解决方法
这种情况一般发生在“在静态方法里面使用内部类” 测试代码: public class Test { public static void main(String[] args) { A a = new ...
- [hdu4763]next数组的应用
http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目大意:给一个字符串,判断是否可以写成ABACA,B.C表示长度大于等于0的字符串. 方法:ans = ...