Spring 5.x 源码之旅-65深入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下的验证结果当作最终结果的水货们请闭嘴】

 

创建事务信息流程图

传播机制图

AbstractPlatformTransactionManager的getTransaction获取事务

事务的创建是跟事务管理器相关的,也就是:

    	@Override
    	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
    			throws TransactionException {
    
    		
    		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
    		//获取事务
    		Object transaction = doGetTransaction();
    		boolean debugEnabled = logger.isDebugEnabled();
    		//如果当前存在事务
    		if (isExistingTransaction(transaction)) {
    			//处理存在的传播情况
    			return handleExistingTransaction(def, transaction, debugEnabled);
    		}
    
    		// 检查超时
    		if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {//超时时间<-1
    			throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
    		}
    		//当前没有事物存在,检查传播行为
    		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
    			throw new IllegalTransactionStateException(//强制是使用当前事务,没有的话就报异常
    					"No existing transaction found for transaction marked with propagation 'mandatory'");
    		}
    		else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
    				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
    				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
    				//没有当前事务的话,REQUIRED,REQUIRES_NEW,NESTED挂起的是空事务,然后创建一个新事务
    			SuspendedResourcesHolder suspendedResources = suspend(null);
    			
    			try {//是否需要新同步
    				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    				DefaultTransactionStatus status = newTransactionStatus(
    						def, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    				doBegin(transaction, def);//开启事务
    				prepareSynchronization(status, def);//设置线程同步状态
    				return status;
    			}
    			catch (RuntimeException | Error ex) {
    				resume(null, suspendedResources);//恢复挂起的事务
    				throw ex;
    			}
    		}
    		else {
    			
    			if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
    				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
    						"isolation level will effectively be ignored: " + def);
    			}
    			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
    			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    		}
    	}

DataSourceTransactionManager的doGetTransaction获取事务

创建一个DataSourceTransactionObject 当做事务,设置是否允许保存点,然后获取连接持有器ConnectionHolder ,里面会存放JDBC的连接,设置给DataSourceTransactionObject ,当然第一次是空的。

    	@Override
    	protected Object doGetTransaction() {
    		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    		txObject.setSavepointAllowed(isNestedTransactionAllowed());
    		ConnectionHolder conHolder =
    				(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
    		txObject.setConnectionHolder(conHolder, false);
    		return txObject;
    	}

DataSourceTransactionManager的isExistingTransaction是否存在当前事务

前面获取了事务,但是是创建的,如果要判断是否有事物存在就要看是否有JDBC连接,事务是否是激活的,当然第一次是没有连接持有器的,所有当前事务不存在:

    	@Override
    	protected boolean isExistingTransaction(Object transaction) {
    		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    		return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());//连接存在,且事务是激活的
    	}

AbstractPlatformTransactionManager的handleExistingTransaction当前存在事务处理

其实跟不存在逻辑,只是有些传播机制需要做特殊处理,比如NEVER发现有存在事务了就报异常了。比如NOT_SUPPORTED就会挂起当前事务,直接准备事务状态就返回了。如果是REQUIRES_NEW的话,挂起当前事务,创建一个新事务状态,并表示需要一个新事务,创建新连接,设置连接参数,同步线程私有变量状态,最后返回。如果是NESTED的话,能用保存点的话就创建一个事务状态,但是不需要新事务,然后创建保存点,剩下的直接准备事务状态就返回了。

    private TransactionStatus handleExistingTransaction(
    			TransactionDefinition definition, Object transaction, boolean debugEnabled)
    			throws TransactionException {
    		//存在事务就报异常
    		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
    			throw new IllegalTransactionStateException(
    					"Existing transaction found for transaction marked with propagation 'never'");
    		}
    		//不支持当前事务
    		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
    			if (debugEnabled) {
    				logger.debug("Suspending current transaction");
    			}
    			Object suspendedResources = suspend(transaction);//挂起当前事务
    			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
    			return prepareTransactionStatus(
    					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    		}
    		//需要新建事务,挂起当前事务
    		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
    			if (debugEnabled) {
    				logger.debug("Suspending current transaction, creating new transaction with name [" +
    						definition.getName() + "]");
    			}
    			SuspendedResourcesHolder suspendedResources = suspend(transaction);//挂起当前事务并返回挂起的资源持有器
    			try {//是否需要新的同步
    				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    				DefaultTransactionStatus status = newTransactionStatus(//创建新的事务状态
    						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    				doBegin(transaction, definition);//准备创建连接开启事务
    				prepareSynchronization(status, definition);//进行线程私有绑定
    				return status;
    			}
    			catch (RuntimeException | Error beginEx) {
    				resumeAfterBeginException(transaction, suspendedResources, beginEx);
    				throw beginEx;
    			}
    		}
    		//嵌套事务
    		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
    			if (!isNestedTransactionAllowed()) {//不允许就报异常
    				throw new NestedTransactionNotSupportedException(
    						"Transaction manager does not allow nested transactions by default - " +
    						"specify 'nestedTransactionAllowed' property with value 'true'");
    			}
    			if (debugEnabled) {
    				logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
    			}
    			if (useSavepointForNestedTransaction()) {
    			
    				DefaultTransactionStatus status =
    						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
    				status.createAndHoldSavepoint();
    				return status;
    			}
    			else {
    				
    				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    				DefaultTransactionStatus status = newTransactionStatus(
    						definition, transaction, true, newSynchronization, debugEnabled, null);
    				doBegin(transaction, definition);
    				prepareSynchronization(status, definition);
    				return status;
    			}
    		}
    
    		
    		...
    		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
    	}

下次再深入细节分析到底是怎么做的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值