Spring 5.x 源码之旅-70深入AOP事务原理七

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

 

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

 

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

处理回滚流程图

处理提交流程图

传播机制图

ConnectionHolder的clear连接持有器的清除

继续上一篇的doCleanupAfterCompletion,连接关闭了,最后连接持有器也应该清除状态。

    	@Override
    	public void clear() {
    		super.clear();
    		this.transactionActive = false;
    		this.savepointsSupported = null;
    		this.savepointCounter = 0;
    	}

ResourceHolderSupport的clear

清除事务同步状态,回滚状态等。

    	public void clear() {
    		this.synchronizedWithTransaction = false;
    		this.rollbackOnly = false;
    		this.deadline = null;
    	}

AbstractPlatformTransactionManager的resume恢复挂起的事务

如果前面有事务被挂起了,现在就要恢复,其实就是把一些属性设置回去。

    	protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
    			throws TransactionException {
    		//一堆属性和状态设置回去
    		if (resourcesHolder != null) {
    			Object suspendedResources = resourcesHolder.suspendedResources;
    			if (suspendedResources != null) {
    				doResume(transaction, suspendedResources);
    			}
    			List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
    			if (suspendedSynchronizations != null) {//如果有挂起同步器的话要设置线程私有变量的值为挂起事务的相关属性
    				TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
    				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
    				TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
    				TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
    				doResumeSynchronization(suspendedSynchronizations);
    			}
    		}
    	}

DataSourceTransactionManager的doResume

将挂起的事务连接持有器和数据源绑定,放入线程私有变量中。

    @Override
    	protected void doResume(@Nullable Object transaction, Object suspendedResources) {
    		TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
    	}

刚好和上一篇的解除绑定相反,把他们放到resourcesmap中。

TransactionAspectSupport的cleanupTransactionInfo清除事务信息

处理完之后,最后还要清除事务信息:


其实就是恢复线程私有变量的状态,设置回老的,因为前面有绑定线程的时候有设置过新的:

    	protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {
    		if (txInfo != null) {
    			txInfo.restoreThreadLocalStatus();
    		}
    	}


至此,回滚处理基本讲完了,接下去看成功完成提交的部分commitTransactionAfterReturning

TransactionAspectSupport的commitTransactionAfterReturning提交事务

调用事务管理器的提交方法。

    	protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
    		if (txInfo != null && txInfo.getTransactionStatus() != null) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
    			}
    			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
    		}
    	}

AbstractPlatformTransactionManager的commit提交事务

这里就是前面我说了,就算没有异常,但是提交的时候也可能会回滚,因为有内层事务可能会标记回滚。所以这里先判断是否状态是否需要本地回滚,也就是设置回滚标记为全局回滚,不会进行回滚,再判断是否需要全局回滚,就是真的执行回滚。但是这里如果是发现有全局回滚,还要进行提交,就会报异常。

    	@Override
    	public final void commit(TransactionStatus status) throws TransactionException {
    		if (status.isCompleted()) {
    			throw new IllegalTransactionStateException(
    					"Transaction is already completed - do not call commit or rollback more than once per transaction");
    		}
    
    		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    		if (defStatus.isLocalRollbackOnly()) {//当前事务状态需要回滚
    			if (defStatus.isDebug()) {
    				logger.debug("Transactional code has requested rollback");
    			}
    			processRollback(defStatus, false);//不可预期的回滚
    			return;
    		}
    		//设置了全局回滚
    		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
    			if (defStatus.isDebug()) {
    				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
    			}
    			processRollback(defStatus, true);//可预期的回滚,可能会报异常
    			return;
    		}
    		//处理提交
    		processCommit(defStatus);
    	}

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值