Spring事务流程源码剖析+传播行为运用案例+心得

Spring源码剖析-Transactional 事务执行流程 看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面小编专门为你量身定制了一套针对知识面不够,也莫慌!还有一整套的,可以瞬间查漏补缺全都是一丢一丢的收集整理纯手打出来的。 阅读详情


总结:Spring的事务本质上就是操作数据库的事务

一、Spring事务流程源码剖析

Spring的声明式事务处理是通过AOP切面实现的核心逻辑在TransactionAspectSupport#invokeWithinTransaction中(这里不在赘述代理类如何生成以及切面何时进入,如有疑问可以参考SpringAOP之代理对象的创建、SpringAOP之代理对象的执行、Spring声明式事务控制原理之声明式事务的重要组件(注解实现)以及之间关系、Spring声明式事务控制原理之声明式事务的重要组件在AOP中的应用)

invokeWithinTransaction中三个主要步骤:
1.createTransactionIfNecessary 获取当前事务
2.completeTransactionAfterThrowing 发生异常时回滚
3.commitTransactionAfterReturning 无异常时提交

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		// 获取事务属性解析器ProxyTransactionManagementConfiguration中注入
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 当前方法上声明式事务的相关属性信息
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		// 获取事务管理器,封装了事务启动、提交、回滚的横切逻辑
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		// 封装了当前方法相关信息
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			// 获取事务详情,开启事务(包含当前事务全部信息,以及上层挂起事务)
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				// 执行原方法
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				// 如果目标方法剖出异常执行回滚操作,并且抛出异常
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// 结合传播属性进行理解,处理挂起的事务
				cleanupTransactionInfo(txInfo);
			}
			// 如果目标方法正常执行执行事务提交操作。
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
					try {
						return invocation.proceedWithInvocation();
					}
					catch (Throwable ex) {
						if (txAttr.rollbackOn(ex)) {
							// A RuntimeException: will lead to a rollback.
							if (ex instanceof RuntimeException) {
								throw (RuntimeException) ex;
							}
							else {
								throw new ThrowableHolderException(ex);
							}
						}
						else {
							// A normal return value: will lead to a commit.
							throwableHolder.throwable = ex;
							return null;
						}
					}
					finally {
						cleanupTransactionInfo(txInfo);
					}
				});

				// Check result state: It might indicate a Throwable to rethrow.
				if (throwableHolder.throwable != null) {
					throw throwableHolder.throwable;
				}
				return result;
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
			catch (TransactionSystemException ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
					ex2.initApplicationException(throwableHolder.throwable);
				}
				throw ex2;
			}
			catch (Throwable ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
				}
				throw ex2;
			}
		}
	}

1.createTransactionIfNecessary 获取当前事务流程分析

在这里插入图片描述

2.completeTransactionAfterThrowing 发生异常时回滚流程分析

在这里插入图片描述

3.commitTransactionAfterReturning 无异常时提交流程分析

在这里插入图片描述

二、传播行为运用案例

在这里插入图片描述

1.经典案例—回滚标记


		  out_method_required1{
		 
		      method_required_1(){
		      		保存数据
		      }
		 
		 
		 	try{
		      method_required_2(){
		     		保存数据
		          throw new RuntimeException;
		      }
		    }catch{
		        吃掉异常
		    }
		 
		  }

问:method_required_1中数据可以保存成功嘛?
	 
答:不会保存成功会一起回滚掉,因为method_required_2回滚时标记了ConnectionHolder为rollbackOnly = true;

2.经典案例2—REQUIRES_NEW传播行为运用


		  out_method_required2{
		     method_required_1(){
		     		保存数据
		     }
		 
		 
		 	try{
		      method_requires_new_2(){
		      		保存数据
		          throw new RuntimeException;
		       }
		    }catch{
		       吃掉异常
		    }
		 
		 }
		 

问:method_required_1会保存成功嘛?
答:会保存成功,因为method_requires_new_2事务的传播行为是REQUIRES_NEW类型,此类型的传播行为会挂起当前事务,重启一个新事务,与之前事务没有任何关系当新建事务执行完毕后在回复挂起的事务。通过操作TransactionSynchronizationManager中的ThreadLocal实现(数据库连接与线程的绑定关系)。

3.经典案例3—NESTED传播模式运用


		  out_method_required3{
		
		  try{
		     method_nested_2(){
		      		保存数据
		         throw new RuntimeException;
		      }
		   }catch{
		       吃掉异常
		    }
		 
		      method_required_1(){
		      		记录日志
		      }

		  }
		 
问:试问method_required_1会保存成功嘛?
答:会保存成功,因为method_nested_2的传播类型是NESTED类型,在触发回滚时会利用保存点进行回滚+清除保存点,不会标记ConnectionHolder为只能回滚状态导致使用当前连接的全部事务回滚;在触发Commit时会清除保存点。故不会导致全局回滚。

4.经典案例4—NESTED传播模式运用2

 		out_method_required3{
		  method_nested_1(){
		      		记录日志
		    }
		 
		  try{
		     method_required_2(){
		     		保存数据
		         throw new RuntimeException;
		       }
		   }catch{
		       吃掉异常
		   }
		 }
问:method_nested_1会保存成功嘛?
答:不会保存成功,method_nested_1采用NESTED的传播模式,当前模式下commit操作会清除保存点,但不会真正操作Commit,会跟随外层事务一起提交回滚,method_required_2采用的是REQUIRED传播模式,发生回滚是会标记ConnectionHolder为只能回滚状态,导致外层事务也会回滚从而导致method_nested_1回滚保存失败。

三、心得

在内层事务的视角解读三种传播行为:

1.REQUIRED是成功了与外层事务一起Commit或着一起Rollback,失败了标记使用当前连接的事务未RollbackOnly=true状态,会导致使用当前Connection连接的事一起回滚包括外层事务。
2.REQUIRES_NEW是挂起外层事务,Commit和Rollback都与外层事务无关,只自己提交或者回滚,当回滚或提交结束后会回复外层挂起事务;
3.NESTED是成功了与外层事务一起Commit或着一起Rollback,失败了自己回滚不影响外层事务;

NESTD和REQUIRES_NEW运用场景

如果存在"业务逻辑成功需要记录日志,失败日志一起回滚,且日志记录异常不能影响业务逻辑"这种需求。
建议业务逻辑使用REQUIRED传播行为放在前面,记录日志使用NESTED传播行为放在后面。
不建议使用REQUIRES_NEW这种传播行为,因为当执行REQUIRES_NEW传播行为的事务横切逻辑时会多开一个Connection连接,比起NESTED更占用资源。
Spring在Transaction事务传播行为种类 Spring在Transaction事务传播行为种类,希望对大家有所帮助 立即下载

相关推荐

SPRING事务传播特性&事务隔离级别

事务传播特性&事务隔离级别 详细的事务传播特性&事务隔离级别

Spring事务底层源码解析(二)

同理,执行完insertTransactionOne方法之后,继续执行insertTransactionTwo方法,流程跟insertTransactionOne相同,当这两个方法执行完毕的时候,那么就又回到了testTransaction1方法,此时他的newTransaction为true,那么就会执行doCommit方法将事务进行提交。如果传播属性是PROPAGATION_REQUIRED,此时b方法这个属性应该为false,就表名方法b没有开启新事务,复用a方法的事务,最终提交由a方法提交。

qq_40228720的博客 1425

ANSYS命令流黑箱揭秘:流体渗透压力载荷的七种收敛优化策略

本文深入解析ANSYS Workbench中流体渗透压力载荷的七种收敛优化策略,重点探讨接触探测点迭代逻辑、PPCN阈值动态调整及FPAT参数优化等关键技术。通过命令流示例和实战技巧,帮助工程师有效解决流体与结构相互作用仿真中的收敛难题,提升计算效率和精度。

weixin_29274337的博客 517

springboot/spring事务传播机制

spring事务传播机制

农夫三拳 639

ArcGIS中地理坐标系与投影坐标系以及投影转换

简单介绍arcgis软件中坐标系定义、设置和常见问题。

weixin_41399650的博客 8万+

一起玩儿物联网人工智能小车(ESP32)——48. 利用循迹模块实现循迹小车(三)

摘要:本文介绍循迹小车的接线方法及类的基础知识

一起玩儿科技 1134

Spring 事务源码(7)—事务的completeTransactionAfterThrowing回滚、commitTransactionAfterReturning提交以及事务源码总结【一万字】

基于最新Spring 5.x,详细介绍了Spring 事务源码,包括completeTransactionAfterThrowing尝试回滚事务、commitTransactionAfterReturning尝试提交事务,cleanupTransactionInfo清理事务信息等等方法。

终生学习践行者 2738

西门子【Automation Framework V1.2】AF架构:从软件栈到高效自动化项目的构建蓝图

本文深入解析西门子Automation Framework V1.2 (AF架构) 的核心价值与实施蓝图。该框架通过定义标准化的软件栈(如TIA Portal V19、STEP7、WinCC Unified)和严格的安装配置流程,将自动化项目开发从依赖个人经验的“手工作坊”模式,转变为高效、可复制的工业化模式。遵循此架构,工程师能快速构建稳定可靠的项目基础,规避环境冲突,从而专注于核心工艺与逻辑设计,大幅提升团队协作与项目交付效率。

weixin_29230059的博客 428

spring事务传播源码解析

前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为。这是Spring为我们提供的强大的工具箱,使用事务传播行可以为我们的开发工作提供许多便利。要想正确的使用工具首先需要了解工具。本文对七种事务传播行为做代码级别的解析。 基础概念 1.什么是事务传播行为? ...

后起秀厚勃发 1181

从零到一:TI AWR1843 Boost EVM与DCA1000 EVM的ADC数据采集实战指南

本文详细介绍了TI AWR1843 Boost EVM与DCA1000 EVM的ADC数据采集实战指南,涵盖硬件连接、软件配置、固件烧录、雷达参数设置及数据处理等关键步骤。通过MATLAB等工具,开发者可高效实现毫米波雷达数据采集,适用于自动驾驶、工业检测等领域。

weixin_29001327的博客 966

边云协同智能进化:大模型与小模型的动态训练与高效部署策略

本文深入探讨了边云协同架构下大模型与小模型的动态训练与高效部署策略。通过物流分拣、医疗影像等实战案例,展示了如何利用边云协作框架实现AI模型的智能进化,显著提升处理效率与准确性。重点解析了动态任务分配、增量学习和知识蒸馏等关键技术,为分布式训练场景提供优化方案。

work3的博客 190

深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理

在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。

2301_81073317的博客 4052

NSIS教程(8): 基于第三方界面库的安装包界面

前面的几篇文章介绍了NSIS的传统界面的安装包和现代界面的安装包的制作方法,也提到了NSIS支持自定义页面(即使用page custom)的特性,自定义页面需要用户自己创建对话框、控件、添加控件响应等等,虽然NSIS提供了nsDialogs.nsh来支持这些功能,但使用起来还是不太方便(需要专门了解这个插件诸多用法),而且不够灵活,所以本文介绍一种终极的自定义界面的安装包解决方案,即完全使用第三方

while(1) { smile(); } 9万+

Spring 事务传播机制源码深度解析

本文深入解析了Spring事务传播机制的源码实现。通过分析AbstractPlatformTransactionManager的核心方法getTransaction(),揭示了Spring处理事务传播的总入口逻辑。重点剖析了handleExistingTransaction()方法对不同传播行为(PROPAGATION_NEVER、NOT_SUPPORTED、REQUIRES_NEW、NESTED等)的处理策略,包括事务挂起、创建新事务、设置保存点等关键操作。特别详细解读了REQUIRES_NEW传播行为的

csdn_tom_168的博客 814

3D打印开源硬件MKS Monster8 V2.0 原理图赏析--更新中

MKS MONSTER8 主板是创客基地为满足市场需求而推出的主板,可用于Voron 2.4机器安装,支Marlin 固件和Klipper固件,支持U盘打印(暂时只有Marlin固件支持),支持TMC驱动UART模式,它包含了3D打印机所需要的主要部件和接口,通过MCU集中控制,是一款功能强大的主板。下面详细分析一下。

我的专栏 7222

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

深入理解 Spring 事务传播行为:从源码角度剖析事务管理的核心实现

深入理解 Spring 事务传播行为:从源码角度剖析事务管理的核心实现

雾里华的博客 1049

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【Spring事务源码实战】一篇文章搞透声明式事务:`@Transactional`的传播行为与回滚机制深度剖析

原则一:事务边界最小化原则“让事务只做它该做的事,不多一秒”基于源码分析,我们认识到事务的本质是数据库连接的占用。减少锁竞争:长时间事务会增加锁持有时间,影响并发性能避免连接泄漏:Spring的声明式事务依赖连接绑定到线程,范围过大会增加泄漏风险提升可预测性:短事务的执行时间更可控,便于容量规划和监控实践检查清单事务方法中是否包含网络IO调用?是否在事务中执行复杂的内存计算?查询操作是否使用了只读事务提示?事务超时时间是否根据SQL执行时间合理设置?原则二:异常处理一致性原则。

持续输出Java相关知识 800

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Spring事务管理源码剖析 @Transactional注解的工作原理与陷阱

《Spring事务管理的实战经验与深度剖析》摘要:本文基于13年Java开发经验,深入探讨Spring事务管理的核心原理与实践陷阱。从@Transactional注解的代理机制、事务传播行为到连接泄露等典型问题,结合真实案例和源码分析,揭示事务失效的八大场景及解决方案。重点解析了REQUIRED与REQUIRES_NEW的差异、MySQL对NESTED传播行为的限制,并提供了分布式事务的Seata实战方案。文章还总结了"事务宪法"六原则,包括短小精悍、设置超时、明确回滚异常等最佳实践,最

七夜zippoe的博客 724

面试基础--- Spring 事务传播机制底层实现原理

严格遵循「同库用传播,跨库用分布式」原则REQUIRES_NEW 必须评估连接池最大容量嵌套事务场景必须测试数据库引擎支持情况事务方法间调用必须通过代理对象(AOPContext)

weixin_43290370的博客 1513

Spring源码剖析9:Spring事务源码剖析

转自:http://www.linkedkeeper.com/detail/blog.action?bid=1045 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章将同步到我的个人博客: www.how2playlife.com ...

AliCoder的博客 975

那些年面试官问过我的 Spring 事务传播行为

2018年的5月,我从深圳匆匆地来到了上海这座陌生的城市。上海很大,很快我就约到了几个面试,其中一家是某总部在杭州做二手车交易的公司。作为刚毕业一年的小菜鸡,我怀着忐忑的心情走进了这家公司在上海的办公地点,面积不大,大概只有不到300平米。当时会议室已经被占满,我坐在工位上答的笔试题。坐在我旁边的小伙伴好心的提醒了我:**“Spring 事务传播行为你掌握的怎么样?等会很可能会问你这个。”** 纳尼?心中一万个草泥马在奔跑。趁着面试官还没到,我用手机匆匆查了下,当时只记得有7种事务传播行为,但是临时抱佛脚,

大鹏的博客 440

Spring 事务源码分析

在前面一期我们分析过Spring AOP的原理,并且在结尾自定义了一个AOP的拦截器简单实现,如果没有弄明白AOP原理的朋友,还是先弄清楚AOP再来看本文,因为Spring事务就是以AOP为基础实现的。提到事务,我们最早学习JDBC的时候,如果要进行数据库操作,通常可以把方法抽象成这样 try{ //关闭自动提交,开启事务 con.setAutoCommit(false); //..... //DML、DQL操作 //提交事务 con.commit(); }catc

weixin_45271492的博客 1346

spring事务传播机制源码学习笔记

传播机制源码

小小少年的博客 350

深入分析spring事务传播行为

阿里大牛带你深入分析spring事务传播行为 2019年03月26日 20:56:57 Java高级开发 阅读数:17 标签: JAVA 编程语言 程序员 架构 spring 更多 个人分类: JAVA高级开发 spring框架封装了很多有用的功能和组件,便于在项目开发中快速高效的调用,其中spring的事务使用非常简单,只需要在用到事务的地方加一行注解即可: 1@Transactio...

java_2017_csdn的博客 507
上一篇: Spring事务传播行为——转载
下一篇: SSM搭建步骤+疑问解答
躺平程序猿
博客等级 码龄8年 4870粉丝 71原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

躺平程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值