当前位置:网站首页>@Transactional注解的失效场景
@Transactional注解的失效场景
2022-07-31 06:54:00 【会说话的皮卡丘】
在开发过程中,我们经常会遇到事物,为了解决这个问题,spring提供了很好的事务管理机制,
java开发过程中主要分为两大类
编程式事务和声明式事务
编程式事务是在编写代码的过程中手动进行事务的操作,代码侵入性较高
关于具体操作主要可以通过
transactionManager.commit
以及
transactionManager.rollback
进行操作
另外一种是声明式编程
@Transactional就是一个很好的例子
@Transactional 可以作用在接口、类、类方法
如果作用于类的话比较好理解,就是对于该类的所有public方法都保证相同的事务属性信息,作用于,作用于方法的话也很好理解,但如果类配置了 @Transactional 的同时方法也配置了 @Transactional 的话,以细粒度的方法级别的 @Transactional 配置为准
不推荐作用于接口,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效
什么是CGLib呢
传统的jdk动态代理与CGLib代理的区别是jdk动态代理的代理类与目标类都继承了相同的接口,这就使得他们要实现相同的接口,那么代理类和目标类的方法名就一样了
CGLib动态代理是代理类去继承目标类,然后重写其中目标类的方法,这样也可以保证代理类拥有目标类的同名方法;
代理类去继承目标类,每次调用代理类的方法都会被方法拦截器拦截,在拦截器中才是调用目标类的该方法的逻辑
咳咳有点跑题了,先继续学习吧
关于@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.SERIALIZABLEtimeout 属性
timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 属性
readOnly :指定事务是否为只读事务,默认值为
false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollbackFor 属性
rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
noRollbackFor属性
noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。
@Transactional失效场景:
如果Transactional注解应用在非public 修饰的方法上,会失效
之所以会失效是因为在Spring AOP 代理时,TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,会间接调用 AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute 方法,获取Transactional 注解的事务配置信息。
protected TransactionAttribute computeTransactionAttribute(Method method,
Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
@Transactional 注解属性 propagation 设置错误
@Transactional 注解属性 rollbackFor 设置错误
同一个类中方法调用,导致@Transactional失效
异常被你的 catch“吃了”导致@Transactional失效:
spring的事务是在调用业务方法之前开始的,业务方法执行完毕之后才执行commit or rollback,事务是否执行取决于是否抛出runtime异常。如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
数据库引擎不支持事务
边栏推荐
- 【面试:并发篇37:多线程:线程池】自定义线程池
- 什么是半波整流器?半波整流器的使用方法
- DAY18: XSS vulnerability
- ‘vite‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
- MySQL详解
- Conditional statements of shell (test, if, case)
- Chapter 9 Exceptions try...except...else...finally
- Client navicat installation tutorial
- 2022.07.14_Daily Question
- 【Go报错】go go.mod file not found in current directory or any parent directory 错误解决
猜你喜欢
一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?
解决安装 Bun 之后出现 zsh compinit: insecure directories, run compaudit for list. Ignore insecure directorie
Tasks and task switching
从入门到一位合格的爬虫师,这几点很重要
解决win11/win10在登陆界面(解锁界面)点击获取每日壁纸无效的问题 - get Daily Lockscreen and Wallpaper - Win11/10的登录界面背景图片在哪里?
CNN--各层的介绍
The Perfect Guide|How to use ODBC for Agentless Oracle Database Monitoring?
Core Tower Electronics won the championship in the Wuhu Division of the 11th China Innovation and Entrepreneurship Competition
MySql数据库优化查询工具
Leetcode952. 按公因数计算最大组件大小
随机推荐
DAY18:XSS 漏洞
电脑开机密码怎么设置?如何给你的电脑加上“安全锁”
DAY18: XSS vulnerability
在 ASP.NET Core 应用程序启动时运行代码的 3 种方法
Pygame Surface对象
基于LSTM的诗词生成
Leetcode952. Calculate maximum component size by common factor
【Go】Go 语言切片(Slice)
Leetcode952. 按公因数计算最大组件大小
进程和线程的区别&&run和start区别与联系
2022.07.13_Daily Question
【 TA - frost Wolf _may - "one hundred plan" 】 art 2.3 hard surface
2022.07.12_每日一题
7/28-7/29 期望+思维+后缀数组+ST表
2022.07.15_Daily Question
庐山谣寄卢侍御虚舟
mysql插入新字段方法
2022.07.24_每日一题
2022.07.22 _ a day
我开发了一个利用 Bun 执行 .ts / .js 文件的 VS Code 插件