Spring事务注解介绍
1、事务介绍
事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。
编程式事务:是指在代码中手动的管理事务的提交、回滚等操作,代码侵入性比较强,如下示例:
try { transactionManager.commit(status);
} catch (Exception e) { transactionManager.rollback(status); throw new InvoiceApplyException("异常失败");
}
声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。
声明式事务也有两种实现方式,一是基于TX和AOP的xml配置文件方式,二种就是基于@Transactional注解了,如
@Transactional
@GetMapping("/addCity")
public String add() { int result = cityMapper.insert(cityInfo);
}
2、@Transactional介绍
1、@Transactional注解可以作用于哪些地方?
@Transactional 可以作用在接口、类、类方法。
作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。
作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效
2、@Transactional注有哪些属性?
propagation属性
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 效果一样。
isolation 属性
isolation :事务的隔离级别,默认值为 Isolation.DEFAULT。
Isolation.DEFAULT:使用底层数据库默认的隔离级别。
Isolation.READ_UNCOMMITTED 读未提交
Isolation.READ_COMMITTED 读已提交
Isolation.REPEATABLE_READ 不可重复读
Isolation.SERIALIZABLE 串行化
timeout 属性
timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 属性
readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollbackFor 属性
rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
noRollbackFor属性
noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。
3、@Transactional失效场景
1、@Transactional 应用在非 public 修饰的方法上
如果Transactional注解应用在非public 修饰的方法上,Transactional将会失效。
注意:protected、private 修饰的方法上使用 @Transactional 注解,虽然事务无效,但不会有任何报错,这是我们很容犯错的一点。
2、@Transactional 注解属性 propagation 设置错误
这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
**3、错误异常,导致失效@Transactional **
rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务,其他异常不会触发回滚事务(包括try catch吞了异常)。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定rollbackFor属性,踩过坑的有当时间转换错误时抛出的异常ParseException 它不是RuntimeException 下异常则不会被回滚。
4、同一个类中方法调用,导致@Transactional失效
开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。当外界调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。那为什么会出现这种情况?其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
5、多线程调用,导致@Transactional失效
spring的事务是通过数据库连接来实现的。当前线程中保存了一个map,key是数据源,value是数据库连接。
源码:private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>(“Transactional resources”);
我们说的同一个事务,其实是指同一个数据库连接,只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务。如 在方法A中使用多线程调用方法B,如果方法B报错了,则方法A事务是不会回滚。
Spring事务注解介绍相关推荐
- Spring事务注解
一.事务特性 @Transactional注解是用于事务控制的,需要知道事务的ACID特征:即原子性(Atomicity,或称不可分割性).一致性(Consistency).隔离性(Isolati ...
- Spring——事务注解@Transactional【建议收藏】
在某些业务场景下,如果一个请求中,需要同时写入多张表的数据或者执行多条sql,为了保证操作的原子性(要么同时成功,要么同时失败),避免数据不一致的情况,我们一般都会用到事务:Spring框架下,我们经 ...
- Spring事务注解实现的原理
Spring事务注解是个典型的Spring AOP的注解.方法上面加上@Transactional,方法就有了事务的能力. 面试中:基于动态代理讲更多的东西.... 为什么呢?--->其实里面核 ...
- Spring——事务注解@Transactional的源码分析
本篇结合我的这篇<Spring事务注解@Transactional>,为第二节[2.Spring声明式事务的原理]的详细说明,debug了被@Transactional包裹的目标方法所在类 ...
- dubbo 注解与spring 事务注解冲突完美解决方案
这几天碰到dubbo 注解与spring 事务注解同时启用dubbo注解无法生效的问题. 在网上找了大部分程序员们贴出的解决方案都没有解决问题.最终在自己的分析下成功解决问题. 解决步骤如下,后面会贴 ...
- MySQL事务隔离级别和Spring事务关系介绍
事务隔离级别介绍 隔离级别 脏读 不可重复读 幻读 未提交读(Read uncommitted) 可能 可能 可能 已提交读(Read committed) 不可能 可能 可能 可重复读(Repeat ...
- spring事务注解@Transactional参数详解
在Spring中进行事务管理操作有两种方式:编程式事务管理和声明式事务管理.这里介绍的是第二种方式. 1.声明式事务管理(底层使用AOP原理): 1>基于注解方式.(本文章基于注解) 2> ...
- Spring事务注解配置
一,spring基于注解式的事务配置方法:@Transactional 1.xml配置 <?xml version="1.0" encoding="UTF-8&qu ...
- 三木之Spring事务注解实现
AOP底层实现原理 动态代理 ( 什么是动态代理 1.代理对象,不需要实现接口 2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型 ...
最新文章
- html表格极细边框,html中表格细边框的四种实现及其比较
- oracle排序使用,很多中函数,不同的效果
- LoadRunner 脚本语言认识
- 【问题收集·知识储备】Xcode只能选择My Mac,不能选择模拟器如何解决?
- 直播间越播越没人,大部分刚开始做直播电商的人都会这样
- 光滑噪声数据常用的方法_数据挖掘部分课后习题
- 数据结构(java语言描述)课后答案_数据结构JAVA语言描述习题答案(刘小晶等主编)pdf总复习.ppt...
- CSS修改input标签中placeholder值的文字样式
- 远程桌面由于以下原因无法连接远程计算机,win10远程桌面提示由于以下原因之一无法连接的解决教程...
- 基于matlab的车牌定位算法设计与实现,原创】基于matlab的汽车牌照识别系统设计与实现...
- Android如何让Fragment加载到Activity中
- AStar 拐点 算法实现AI寻路
- Angular 基础
- 梅赛德斯-奔驰将区块链技术应用于可持续交易账簿及供应链
- 安装完anaconda怎么创建新的虚拟环境
- java项目-第34期基于SpringBoot实现的中小医院HIS管理系统【毕业设计】
- 小青蛙oracle跟踪,在小青蛙TOAD中用oracle语句写
- Spring定时器之翘楚-Quartz
- 手撕TreeMap红黑树
- linux显示桌面命令,linux显示桌面快捷键设置
热门文章
- Grafana 未经授权任意访问漏洞(CVE-2022-32275)
- (无报错)Java截取视频生成Gif动图 视频转gif动态图 视频截帧取图 java实现方式
- Python 3中的lambda函数使用
- java 圆角组件_Java圆角和透明的边框
- 中柏pad7安装linux,接个键盘就是电脑 中柏EZpad 7改变移动办公体验
- android 自定义view仿支付宝写五褔及播放
- 【Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!
- spring web 知识点过一遍
- php为什么没有npm,在phpstorm的terminal中输入npm显示不是内部或外部命令
- 设备树 之pinctrl[通俗易懂]