使用@Transactional应注意的问题
使用@Transactional应注意的问题
@Transactional 基本原理概述
在应用系统调用声明@Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据@Transactional 的属性配置信息,这个代理对象决定该声明@Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常,利用抽象事务管理器AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务。
你需要注意的事
- @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能
- Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。
- 当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因此,还是在具体的类上使用 @Transactional 注解比较好。
- 避免 Spring 的 AOP 的自调用问题:自调用就是方法A内调用本类的另一个加上事务注解的方法B时,方法B中对数据库的操作是不带事务的。
Spring AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。
失效原因:
方法one方法two都是public的:
- classA中 ,任意要调用classB的方法,是通过spring代理的方式,那么spring的注解才会生效
- classA中,方法one 调用同class内的方法two,即this调用,spring注解不会生效(例如@Cachable,@Transaction)
解决方法
既然已知原因,那么解决的方法就有了,核心思想就是如何获得动态代理对象,而不是使用this去调用。
方案一:使用AspectJ代理
@Service
public class OrderService {private void insert() {insertOrder();}
@Transactionalpublic void insertOrder() {//insert log info//insertOrder//updateAccount}
}
insertOrder 尽管有@Transactional 注解,但它被内部方法 insert 调用,事务被忽略,出现异常事务不会发生回滚。
上面的两个问题@Transactional 注解只应用到 public 方法和自调用问题,是由于使用 Spring AOP 代理造成的。为解决这两个问题,可以使用 AspectJ取代 Spring AOP 代理,但现在有更好的解决方法。
方案二:利用AopContext.currentProxy()方法获得代理
方法的意思是尝试返回当前AOP代理。这种做法非常简洁,但是在默认情况下是不起作用的!因为AopContext中拿不到currentProxy,会报空指针。需要一些额外的配置,但不能对所有的注解拦截都有效,这是因为这些注解不是用的AspectJ代理,如果是@Transactional事务注解的话, 则是生效的,具体细节要翻源码了,这里不推荐使用。
方案三:通过ApplicationContext来获得动态代理对象(推荐)
@Component
public class AsyncService implements ApplicationContextAware {private ApplicationContext applicationContext;public void async1() {System.out.println("1:" + Thread.currentThread().getName());// 使用AppicationContext来获得动态代理的bean,然后再执行你调用的方法this.applicationContext.getBean(AsyncService.class).async2();}@Asyncpublic void async2() {System.out.println("2:" + Thread.currentThread().getName());}// 注入ApplicationContext@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}
转载于:https://www.cnblogs.com/keeya/p/11180612.html
使用@Transactional应注意的问题相关推荐
- 写出漂亮代码的45个小技巧
不知道大家有没有经历过维护一个已经离职的人的代码的痛苦,一个方法写老长,还有很多的if else ,根本无法阅读,更不知道代码背后的含义,最重要的是没有人可以问,此时只能心里默默地问候这个留坑的兄弟. ...
- 写出漂亮代码的45个小技巧,真好用
大家好,我是三友~~ 不知道大家有没有经历过维护一个已经离职的人的代码的痛苦,一个方法写老长,还有很多的if else ,根本无法阅读,更不知道代码背后的含义,最重要的是没有人可以问,此时只能心里默默 ...
- 这45个小技巧,帮你写出一手同事都羡慕的漂亮代码!
这45个小技巧,帮你写出一手同事都羡慕的漂亮代码! 不知道大家有没有经历过维护一个已经离职的人的代码的痛苦,一个方法写老长,还有很多的if else ,根本无法阅读,更不知道代码背后的含义,最重要的是 ...
- 使用这45个小技巧,帮助你写出更优雅的代码
前言 不知道大家有没有经历过维护一个已经离职的人的代码的痛苦,一个方法写老长,还有很多的if else ,根本无法阅读,更不知道代码背后的含义,最重要的是没有人可以问,此时只能心里默默地问候这个留坑的 ...
- Spring_Spring@Transactional
Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例 ...
- Spring @Transactional (一)
Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例 ...
- @Transactional事务的使用和注意事项及其属性
事务管理 提示 @Transactional注解只能应用到public可见度的方法上,可以被应用于接口定义和接口方法,方法会覆盖类上面声明的事务. 示例: 例如用户新增需要插入用户表.用户与岗位关联表 ...
- SSM框架中使用Spring的@Transactional注解进行事务管理
一 介绍 在企业级应用中,保护数据的完整性是非常重要的一件事.因此不管应用的性能是多么的高.界面是多么的好看,如果在转账的过程中出现了意外导致用户的账号金额发生错误,那么这样的应用程序也是不可接受的 ...
- Spring @Transactional实际如何工作?
在本文中,我们将深入探讨Spring事务管理. 我们将讨论@Transactional在@Transactional如何真正工作. 其他即将发布的帖子将包括: 如何使用传播和隔离等功能 主要陷阱是什么 ...
最新文章
- 安卓项目查手机电量功能_不做低头族,一键开启手机上的这一功能,手机信息随时查...
- Python 之vim编写python自动补全
- Eclipse 启动问题:'Initilizing Java Tooling' has encountered a problem(。。。)
- 基于Android NDK的交叉编译
- vue商城源码_一个标星 5.2k+ 的牛逼开源商城系统
- 任务管理器在右下角的图标不显示
- [react] 请说说react中Portal是什么?
- 运维自动化之使用PHP+MYSQL+SHELL打造私有监控系统(七)
- 【原创】纯CSS 仿U9论坛 箭形导航栏 兼容IE6+IE7+FF
- Kotlin 文档入门-函数 集合
- 最全的PHP后台管理系统源码
- anaconda版本选择_Anaconda简介
- Vue中数组的响应式操作
- 【模式串匹配】Aho-Corasick algorithm - AC字符串匹配算法实现与测试【Python】
- 转载: WebKit介绍及总结(一)
- 《微信小程序案例12》图片识别功能
- kafka是什么?主要用在什么场景
- Asciinema终端SSH录屏神器使用
- 土是独体字结构吗_发是独体字结构吗
- Neural-Motifs 源码解读(3):RelModel类