Transaction 在同一个类中不生效
参考:https://blog.csdn.net/qq_30336433/article/details/83338835
最近在开发项目中踩到一个坑,以此记录下来。以备后来人借鉴
1、相信使用spring开发的小伙伴对@Transaction这个注解应该不会陌生。
spring提供了非常强大的事务管理机制,之前一直以为只要在方法上加上@Transaction就万事大吉了

但是最近发现有些情况下 这个注解会失效。
当这个方法被同一个类调用的时候,spring无法将这个方法加到事务管理中。
下面我们来看看为什么会失效?
其实 spring的@Transactional事务生效的一个前提是方法调用前经过拦截器TransactionInterceptor , 也就是说只有通过TransactionInterceptor拦截器的方法才会被加入到Spring事务管理中,
查看spring源码可以知道,在AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice方法中会调用方法中获取@Transactional注解,如果有该注解则启用事务,否则不启用注解

这个方法是通过spring的AOP类CglibAopProxy的内部类DynamicAdviseInterceptor调用的,而DynamicAdvisedInterceptor继承了MethodInterceptor,用于拦截方法调用,并从中获取调用链。
如果是在同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用,必须将方法放入另外一个类中,并且该类通过spring注入
总结一下:Transactional是Spring提供的事务管理注解
spring 采用动态代理(AOP)实现对Bean的管理和切片,它为我们的每个class生成一个代理对象,只有在代理对象之间进行调用时,可以触发切面逻辑。
而在同一个类中,方法B调用A,调用的事元对象的方法,而不是通过代理对象,所以spring无法切到这次调用,也就是无法通过注解保证事务性。
解决方案:
- 可以将方法放入另一个类,并且该类通过spring注入,即符合了在对象之间调用的条件。
- 获取本对象的代理对象,再进行调用。具体操作如:
1)Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy=“true”/>
2)在xxxServiceImpl中,用(xxxService)(AopContext.currentProxy()),获取到xxxService的代理类,再调用事务方法,强行经过代理类,激活事务切面。 - 很多时候,方法内调用又希望激活事务,是由于同一个方法既有DAO操作又有I/O等耗时操作,不想让耗时的I/O造成事务的太长耗时(比如新增商品同时需要写入库存)。此时,可以将I/O做成异步操作(如加入线程池),而加入线程池的操作即便加入事务也不会导致事务太长,问题可以迎刃而解。
???这条不太懂
Transaction 在同一个类中不生效的更多相关文章
- SpringCache @Cacheable 在同一个类中调用方法,导致缓存不生效的问题及解决办法
由于项目需要使用SpringCache来做一点缓存,但自己之前没有使用过(其实是没有听过)SpringCache,于是,必须先学习之. 在网上找到一篇文章,比较好,就先学习了,地址是: https:/ ...
- Spring @Cacheable注解 && 事务@Transactional 在同一个类中的方法调用不生效
@Cacheable 注解在对象内部调用不会生效 代码示例:ProductServiceImpl.java public List<ProductInfoVO> getProductLis ...
- 分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案
问题: 在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性.但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了. 当这个方 ...
- 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...
- 【转】在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考 原文链接 @Transactional does not work on method level 描述 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational) ...
- @Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题
https://blog.csdn.net/u010235716/article/details/90171802 1. 事务的4种特性 序号 参数 含义1 原子性(Atomicity) ...
- Spring同一个类中的注解方法调用AOP失效问题总结
public interface XxxService { // a -> b void a(); void b(); } @Slf4j public class XxxServiceImpl ...
- 《同一个类中不同方法之间的调用相关问题(省略的类名或者this)》
//同一个类中不同方法之间的调用相关问题(省略的类名或者this) class A { public void B() { System.out.println("b方法运行"); ...
- 梳理:python—同一个类中的方法调用
为什么突然在此提到这个梳理问题呢? 因为在自己实践综合练习学过的知识时,突然觉得有些知识点的运用总是不成功,于是翻过课本进行回顾,总是觉得是对的,可是当再进一步思考“既然是对的,为什么在程序中总是不成 ...
随机推荐
- 正则表达式——POSIX字符组
前面介绍了常用的字符组,但是在某些文档中,你可能会发现类似[:digit:].[:lower:]之类的字符组,看起来不难理解(digit就是"数字",lower就是"小写 ...
- linux串口编程--cssl库
cssl库使用方法概括: 1.cssl_t *ser; //定义一个串口结构体 2.cssl_start(); //使用cssl串口库 3.cssl_open(); //打开并配置串口,参数: 串口名 ...
- ubuntu终端代理之proxychains
命令行代理 安装proxychains sudo apt install proxychains 配置proxychains sudo vim /etc/proxychains.conf 在proxy ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- Ubuntu 安装 ansible
sudo apt update sudo apt-get install software-properties-common sudo apt-add-repository --yes ppa:an ...
- Google authenticator 谷歌身份验证,实现动态口令
Google authenticator 谷歌身份验证,实现动态口令 google authenticator php 服务端 使用PHP类 require_once '../PHPGangsta/G ...
- SSH简单概念
Spring:轻量级控制反转(IoC)和面向切面(AOP)的容器框架,让对象与对象之间的关系通过配置文件来管理,减低耦合度 IoC:凡是在容器中配置过的对象才会有Spring提供的服务和功能 AOP: ...
- Maya2014下载安装与激活
目录 1. 更多推荐 2. 下载地址 2.1. OneDrive 2.2. 其他下载地址 3. 激活步骤 1. 更多推荐 其他Maya版本的下载与激活:https://www.cnblogs.com/ ...
- C# 获取一个文件的MD5值
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- 基于TMS320C6678、FPGA XC5VLX110T的6U CPCI 8路光纤信号处理卡
基于TMS320C6678.FPGA XC5VLX110T的6U CPCI 8路光纤信号处理卡 1.板卡概述 本板卡由我公司自主研发,基于CPCI架构,符合CPCI2.0标准,采用两片TI DSP T ...