@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 ...
随机推荐
- 操作系统实验——PV操作实现生产者消费者模型
操作系统PV操作之--生产者消费者模型 个人博客主页 参考资料: Java实现PV操作 | 生产者与消费者 浙大公开课 在操作系统的多进程.多线程操作中经常会有因为同步.互斥等等问题引发出的一系列问题 ...
- 实现简单网页rtmp直播:nginx+ckplayer+linux
一.安装nginx 安装带有rtmp模块的nginx服务器(其它支持rtmp协议的流媒体服务器像easydarwin.srs等+Apache等web服务器也可以),此处使用nginx服务器,简单方便. ...
- 【5min+】美化API,包装AspNetCore的返回结果
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- Print输出颜色字体方法
书写格式: 开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m 注意:开头部分的三个参数:显示方式,前景色,背景色是可选参数,可以只写其中的某一个:另外由于 ...
- Centos7下设置ceph 12.2.1 (luminous)dashboard UI监控功能
前言 本文所使用的集群是作者在博客 Centos7下部署ceph 12.2.1 (luminous)集群及RBD使用 中所搭建的集群 dashboard是为了完成对集群状态进行UI监控所开发的功能, ...
- P4526 【模板】自适应辛普森法2
P4526 [模板]自适应辛普森法2 #include <bits/stdc++.h> using namespace std; ; double a; inline double f(d ...
- MVC4.0接口学习
/// <summary> /// 正则验证身份证号是否合法 /// </summary> /// <param name="sIdCard"> ...
- Java并发编程入门(一)
一.为什么要并发? 出现背景:操作系统的出现,使计算机同时运行多个程序成为可能. 1.目的: 资源利用率.某些时候,程序必须等待一些外部操作完成(IO)才能继续运行,在等待时间运行其他程序,可以有效提 ...
- 本地安装并运行http-server、browser-sync、webpack
有一些自带命令的辅助开发.测试类的工具,官方都推荐全局安装,如果不想全局安装只想在某个项目下用该怎么办呢? 如http-server.browser-sync.webpack这种自带CLI的工具 使用 ...
- redis 启动停止重启
启动服务: service redis start 停止服务: service redis stop 重启服务: service redis restart