@Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题
https://blog.csdn.net/u010235716/article/details/90171802
1. 事务的4种特性
序号 参数 含义
1 原子性(Atomicity) 事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。
2 一致性(Consistemcy) 事务前后,数据库的状态都满足所有的完整性约束。
3 隔离性(Isolation) 并发执行的事务是隔离的,一个不影响一个。通过设置数据库的隔离级别,可以达到不同的隔离效果
4 持久性(Durability) 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
2.Transactional()控制事务传播的配置项目(默认Propagation.REQUIRED)
@Transactional(propagation=Propagation.REQUIRED) //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT) //控制事务隔离级别。默认跟数据库的隔离级别相同
@Transactional(readOnly=false) //控制事务可读写、只可读。默认可读写
@Transactional(timeout=30) //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
@Transactional(rollbackFor=RuntimeException.class) //控制事务遇到哪些异常会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException) //同上
@Transactional(noRollbackFor=NullPointerException.class) //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上
3.事务的7中传播特性4. 事务的传播案例:
序号 传播行为 含义
1 REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
2 SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3 MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4 NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行
5 NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常
6 REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个已经存在的事务挂起
7 NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务
4.举个上手的按例:事务在A类的a()方法中调用B类的b()方法的传播案例
A.a() B.b()的事务配置 a()没有事务的结果 a()有事务的结果
REQUIRED b()创建自己的事务; b()接受a()的事务
SUPPORTS b()不创建自己的事务; b()接受a()的事务
MANDATORY b()报异常 b()接受a()的事务
NESTED b()创建自己的事务; b()接受a()的事务,成为a()嵌套的子事务
NEVER b()不创建自己的事务; b()报异常
REQUIRES_NEW b()创建自己的事务; b()不接受a()的事务,b()先执行,内层事务失败不会影响外层事务
NOT_SUPPORTED b()不创建自己的事务; b()不接受a()的事务,b()先执行
spring 事务处理中,同一个类中:A方法(无事务)调B方法(有事务),事务不生效问题
详见:https://blog.csdn.net/liming19890713/article/details/79225894
https://blog.csdn.net/m0_38027656/article/details/84190949
https://blog.csdn.net/levae1024/article/details/82998386
研究源码、调试程序得出结论:
A如果没有受事务管理: 则线程内的connection 的 autoCommit为true。
B得到事务时事务传播特性依然生效,得到的还是A使用的connection,但是 不会改变autoCommit的属性。
所以B当中是按照每条sql进行提交的。
解决办法:
可以把方法B放到另外一个service或者dao,然后把这个server或者dao通过@Autowired注入到方法A的bean里面,这样即使方法A没用事务,方法B也可以执行自己的事务了。
Spring 事务机制回顾
Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务. 结果造成开发人员在设计 事务方法时束手束脚,生怕一不小心就踩到地雷。
其实这是不认识Spring事务传播机制而造成的误解,Spring对事务控制的支持统一在TransactionDefinition类中描述,该类有以下 几个重要的接口方法:
int getPropagationBehavior():事务的传播行为
int getIsolationLevel():事务的隔离级别
int getTimeout():事务的过期时间
boolean isReadOnly():事务的读写特性
除了事务的传播行为外,事务的其他特性Spring是借助底层资源的功能来完成的,Spring无非只充当个代理的角色。但是事务的传播行为却是Spring凭借自身的框架提供的功能 ;
Spring事务传播属性:
所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持以下7种事务传播行为
Spring事务传播属性:
1.propagation-required: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就新建一个事务;
2.propagation-supports: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就以非事务的方式执行;
3.propagation-mandatory: 支持当前事务,如果有就加入当前事务中;如果当前没有事务,就抛出异常;
4.propagation-requires_new: 新建事务,如果当前存在事务,就把当前事务挂起;如果当前方法没有事务,就新建事务;
5.propagation-not-supported: 以非事务方式执行,如果当前方法存在事务就挂起当前事务;如果当前方法不存在事务,就以非事务方式执行;
6.propagation-never: 以非事务方式执行,如果当前方法存在事务就抛出异常;如果当前方法不存在事务,就以非事务方式执行;
7.propagation-nested: 如果当前方法有事务,则在嵌套事务内执行;如果当前方法没有事务,则与required操作类似;
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)
在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的
@Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题的更多相关文章
- Spring @Cacheable注解 && 事务@Transactional 在同一个类中的方法调用不生效
@Cacheable 注解在对象内部调用不会生效 代码示例:ProductServiceImpl.java public List<ProductInfoVO> getProductLis ...
- 分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案
问题: 在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性.但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了. 当这个方 ...
- Spring事务:调用同一个类中的方法
问题: 如果同一个类中有方法:methodA(); methodB().methodA()没有开启事务,methodB()开启了事务 且methodA()会调用methodB(). 那么,method ...
- Spring同一个类中的注解方法调用AOP失效问题总结
public interface XxxService { // a -> b void a(); void b(); } @Slf4j public class XxxServiceImpl ...
- 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...
- 【转】在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考 原文链接 @Transactional does not work on method level 描述 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational) ...
- SpringCache @Cacheable 在同一个类中调用方法,导致缓存不生效的问题及解决办法
由于项目需要使用SpringCache来做一点缓存,但自己之前没有使用过(其实是没有听过)SpringCache,于是,必须先学习之. 在网上找到一篇文章,比较好,就先学习了,地址是: https:/ ...
- java中方法内可以调用同一个类中的方法
在同一个类中,java的普通方法的相互调用,可以使用this+点号+方法名,也可省略this+点号,java编 译器会自动补上.
- 梳理:python—同一个类中的方法调用
为什么突然在此提到这个梳理问题呢? 因为在自己实践综合练习学过的知识时,突然觉得有些知识点的运用总是不成功,于是翻过课本进行回顾,总是觉得是对的,可是当再进一步思考“既然是对的,为什么在程序中总是不成 ...
随机推荐
- php 微信公众平台OAuth2.0网页授权,获取用户信息代码类封装demo
get_wx_data.php <?php /** * 获取微信用户信息 * @author: Lucky hypo */ class GetWxData{ private $appid = ' ...
- NSGA,NSGA-II,Epsilon-MOEA,DE C语言Deb教授原版代码
NSGA,NSGA-II,Epsilon-MOEA,Basic Differential Evolution (DE) C语言Deb教授原版代码地址 觉得有用的话,欢迎一起讨论相互学习~[Follow ...
- 在tomcat下context.xml中配置各种数据库连接池
作者:郑文亮 Tomcat6的服务器配置文件放在 ${tomcat6}/conf 目录底下.我们可以在这里找到 server.xml 和 context.xml.当然,还有其他一些资源文件.但是在在本 ...
- php程序无法记录log情况下可尝试下面方法记录log
error_reporting(E_ERROR | E_PARSE); function shutdownCallback(){ $arrError = error_get_last(); // ...
- [转]动态规划DP的分类
链接地址:http://www.cnblogs.com/Renyi-Fan/p/9285495.html
- chrome浏览器调试JS代码
是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容.嗯~,用这 ...
- 使用docker搭建FastDFS文件系统
1.首先下载FastDFS文件系统的docker镜像 docker search fastdfs 2.使用docker镜像构建tracker容器(跟踪服务器,起到调度的作用): docker run ...
- C#自带的Version判断版本号的大小
Version version1 = new Version("1.0.0.25"); Version version2 = new Version("1.0.0.24& ...
- android基础---->ContentProvider的使用
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性.目前,使用内容提 ...
- TCP/IP学习笔记9--以太网之基本概念1: 分类,连接方式
时间是变化的财富.时钟模仿它,却只有变化而无财富. -- 泰戈尔 以太网(Ethernet)一词源于Ether(以太), 是介质的意思.在爱因斯坦哥们提出量子力学之前,人们普遍认为宇宙空间充满以太,并 ...