Spring技术原理——事务的创建,挂起,回归,提交(事务拦截器和抽象事务管理器)

在涉及单个数据库局部事务的事务处理中,事务的最终实现和数据库的支持是紧密相关的。对局部数据库事务来说,一个事务处理的操作单元往往对应着一系列的数据库操作。

Spring事务处理主要分以下三个主要的过程:

(1)读取和处理在Spring IoC容器中配置的事务处理属性,并转化为Spring事务处理所需要的内部数据结构。这里涉及到的类是TransactionAttributeSourceAdvisor类。

(2)Spring的事务处理模块是通过AOP功能来实现声明式事务处理的,通用的事务处理过程包括:处理事务配置属性;事务配置属性与线程绑定等。

TransactionProxyFactoryBean是Spring中管理事务的IoC容器,通过它生成Proxy对象,通过TransactionInterceptor来完成对代理方法的拦截,正是这些AOP的拦截功能,将事务处理的功能编织进来。

(3)底层事务处理实现。Spring中底层事务处理的实现交由PlatformTransactionManager的具体实现类来实现,如DataSourceTransactionManager和HibernateTransactionManager等。

TransactionProxyFactoryBean解析(这只是实现事务的一种方法,其他类也能实现事务,例如DataSourceTransactionManager!!!)

public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean  
        implements BeanFactoryAware {  
    
    private Pointcut pointcut;  
    //通过Spring IoC容器依赖注入的PlatformTransactionManager事务管理器  
    public void setTransactionManager(PlatformTransactionManager transactionManager) {  
    this.transactionInterceptor.setTransactionManager(transactionManager);  
    }  
    //通过依赖注入设置事务属性,以Properties形式存放的事务属性的key是方法名,  
    //value是事务属性描述,注入到TransactionInterceptor中  
    public void setTransactionAttributes(Properties transactionAttributes) {  
    this.transactionInterceptor.setTransactionAttributes(transactionAttributes);  
    }  
    //通过依赖注入设置事务属性源,通过事务属性源可以找到需要使用的事务属性  
    public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {  
    this.transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);  
    }  
    //通过依赖注入设置事务切入点,事务切入点根据触发条件调用事务拦截器  
    public void setPointcut(Pointcut pointcut) {  
        this.pointcut = pointcut;  
    }  
    //为事务拦截器设置管理事务的容器  
    public void setBeanFactory(BeanFactory beanFactory) {  
        this.transactionInterceptor.setBeanFactory(beanFactory);  
    }  
//创建Spring AOP事务处理的通知器Advisor  
    protected Object createMainInterceptor() {  
        //调用事务拦截器的方法,检查必需的属性是否设置  
        this.transactionInterceptor.afterPropertiesSet();  
        //如果在Spring配置中设置了事务切入点  
        if (this.pointcut != null) {  
            //使用Spring默认的通知器封装事务切入点和事务拦截器  
            return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);  
        }  
        //如果在Spring配置中没有设置事务切入点  
        else {  
            //使用TransactionAttributeSourceAdvisor封装默认的事务切入点  
            return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);  
        }  
    }  
}   

TransactionInterceptor的调用时机,完成了Bean的依赖注入后:


 

可以看到在AbstractSingletonProxyFactoryBean中的afterPropertiesSet方法中,调用了createMainInterceptor

//InitializingBean接口的实现方法,IoC容器初始化完成之后的回调方法  
public void afterPropertiesSet() {  
        //事务的目标对象不能为空  
        if (this.target == null) {  
            throw new IllegalArgumentException("Property 'target' is required");  
        }  
        //事务目标对象必须是Bean引用,不能是Bean名称  
        if (this.target instanceof String) {  
            throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");  
        }  
        //如果代理类加载器为null,则使用默认的类加载器作用代理类加载器  
        if (this.proxyClassLoader == null) {  
            this.proxyClassLoader = ClassUtils.getDefaultClassLoader();  
        }  
//创建代理工厂,Spring事务管理容器TransactionProxyFactoryBean通过ProxyFactory完成AOP的基本功能,ProxyFactory提供事务代理对象,并将事务拦截器设置为事务目标对象方法的拦截器  
        ProxyFactory proxyFactory = new ProxyFactory();  
        //如果在事务拦截器之前配置了额外的拦截器  
        if (this.preInterceptors != null) {  
            //将这些事务之前的额外拦截器添加到通知器中  
            for (Object interceptor : this.preInterceptors) {  
    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));  
            }  
        }  
//加入Spring AOP事务处理通知器,createMainInterceptor()方法  
//由子类TransactionProxyFactoryBean提供实现    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));  
        //如果在事务拦截器之后配置了额外拦截器  
        if (this.postInterceptors != null) {  
            //将这些事务之后的额外拦截器添加到通知器中  
            for (Object interceptor : this.postInterceptors) {  
    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));  
            }  
        }  
        //从当前容器中复制事务AOP相关配置到ProxyFactory中  
        proxyFactory.copyFrom(this);  
        //创建AOP的目标源  
        TargetSource targetSource = createTargetSource(this.target);  
        //为ProxyFactory设置AOP目标源  
        proxyFactory.setTargetSource(targetSource);  
        //如果事务配置使用了代理接口  
        if (this.proxyInterfaces != null) {  
            //为ProxyFactory设置代理接口  
            proxyFactory.setInterfaces(this.proxyInterfaces);  
        }  
        //如果事务代理不是直接应用于目标类或者接口  
        else if (!isProxyTargetClass()) {  
            //将目标源的所有接口都设置为ProxyFactory的接口  
            proxyFactory.setInterfaces(  
    ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));  
        }  
        //ProxyFactory对象根据给定的类加载器创建事务代理对象  
        //具体的创建过程我们在Spring的AOP源码分析中已经分析过,Spring根据是否  
        //实现接口而分别调用JDK动态代理或者CGLIB方式创建AOP代理对象  
        this.proxy = proxyFactory.getProxy(this.proxyClassLoader);  
    }  

事务拦截器TransactionInterceptor的实现

管理Spring事务的IoC容器TransactionProxyFactoryBean已经完成了事务配置的读取,设置好了事务拦截器和切入点。当应用调用被配置事务的方法时,首先通过getObject方法向Spring事务管理容器索取被被管理方法的事务属性,触发调用事务拦截器的拦截方法进行事务处理。

在对Spring AOP源码分析中关于AOP代理如何起作用时,我们知道Spring的AOP代理通过invoke回调方法对切入点方法进行拦截处理,这个invoke方法是AOP联盟的方法拦截器MethodInterceptor接口中定义的方法,用于对AOP代理对象的方法进行包装处理。事务拦截器TransactionInterceptor正是通过这个invoke拦截方法实现事务的拦截处理,源码如下:

//事务拦截器的拦截方法  
public Object invoke(final MethodInvocation invocation) throws Throwable {  
        //通过AOP获取事务的目标类  
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);  
        //通过事务属性源TransactionAttributeSource读取事务的属性配置,即调用上面名称匹配  
        //事务属性源NameMatchTransactionAttributeSource的方法  
        final TransactionAttribute txAttr =  
    getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);  
        //获取Spring事务管理IoC容器配置的事务处理器  
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);  
        //获取目标类指定方法的事务连接点  
        final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);  

/*
 * 区分不同类型的PlatformTransactionManager事务处理器,不同类型的事务处理器调用方式不同。对 
 * CallbackPreferringPlatformTransactionManager,需要回调函数来实现事务的创建和提交,对非 
 * CallbackPreferringPlatformTransactionManager来说,则不需要使用回调函数来实现事务处理。          
*/
        //非CallbackPreferringPlatformTransactionManager类型的事务处理器  
        if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {  
            //创建事务,将当前事务状态和信息保存到TransactionInfo对象中  
            TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);  
            Object retVal = null;  
            try {  
                //沿着拦截器链调用处理,使得最后目标对象的方法得到调用  
                retVal = invocation.proceed();  
            }  
            catch (Throwable ex) {  
                //在调用拦截器拦过程中出现异常,则根据事务配置进行提交或回滚处理  
                completeTransactionAfterThrowing(txInfo, ex);  
                throw ex;  
            }  
            //清除与当前线程绑定的事务信息  
            finally {  
                cleanupTransactionInfo(txInfo);  
            }  
            //通过事务处理器来对事务进行提交  
            commitTransactionAfterReturning(txInfo);  
            return retVal;  
        }  
        //CallbackPreferringPlatformTransactionManager类型的事务处理器  
        else {  
            //通过回调函数对事务进行处理  
            try {  
                //执行实现TransactionCallback接口的doInTransaction回调方法  
                Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,  
                        new TransactionCallback<Object>() {  
                            //实现TransactionCallback接口匿名内部类的回调方法  
public Object doInTransaction(TransactionStatus status) {  
    //创建和准备事务  
                                TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);  
                                try {  
                                    //沿着拦截器拦调用  
                                    return invocation.proceed();  
                                }  
                                //拦截器链处理过程中产生异常  
                                catch (Throwable ex) {  
                                    //如果事务对异常进行回滚处理  
                                    if (txAttr.rollbackOn(ex)) {  
                                        //如果异常是运行时异常,则事务回滚处理  
                                       if (ex instanceof RuntimeException) {  
                                            throw (RuntimeException) ex;  
                                        }  
                                        //如果不是运行时异常,则提交处理  
                                        else {  
                                            throw new ThrowableHolderException(ex);  
                                        }  
                                    }  
                                    //如果事务对异常不进行回滚处理  
                                    else {  
                                        //提交处理  
                                        return new ThrowableHolder(ex);  
                                    }  
                                }  
                                //清除当前线程绑定的事务信息  
                                finally {  
                                    cleanupTransactionInfo(txInfo);  
                                }  
                            }  
                        }); // 到这里都是execute方法  
                
                //对调用结果异常进行处理。  
                //如果是ThrowableHolder类型的异常,则转换为Throwable抛出  
                if (result instanceof ThrowableHolder) {  
                    throw ((ThrowableHolder) result).getThrowable();  
                }  
                //如果不是ThrowableHolder类型的异常,则异常不做处理直接抛出  
                else {  
                    return result;  
                }  
            }  
            catch (ThrowableHolderException ex) {  
                throw ex.getCause();  
            }  
        }  
    }  

这一层抛出的异常要怎么处理??

事务创建(创建的结果是生成一个TransactionInfo对象)

事务拦截器TransactionInterceptor回调方法invoke通过调用TransactionAspectSupport事务切面支持类中的createTransactionIfNecessary和prepareTransactionInfo方法创建事务对象:

//根据给定的事务属性创建事务对象
protected TransactionInfo createTransactionIfNecessary(
			PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
		//读取事务方法调用的事务配置属性
		if (txAttr != null && txAttr.getName() == null) {
			//如果事务名称为null,则使用方法的名称(事务连接点标识)作为事务名称,
			//调用一个实现DelegatingTransactionAttribute接口的匿名内部类
			txAttr = new DelegatingTransactionAttribute(txAttr) {
				//使用方法名称作为事务名称
				public String getName() {
					return joinpointIdentification;
				}
			};
		}
		//事务状态封装了事务执行的状态信息
		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
				//事务处理器创建事务,并且返回当前事务的状态信息
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		//准备事务信息,事务信息TransactionInfo封装了事务配置和状态信息
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}



 
//准备事务信息
protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,
			TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
		//创建事务信息对象
		TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
		//如果事务属性不为null,需要为方法使用事务
		if (txAttr != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
			}
			//为事务信息对象设置事务状态
			txInfo.newTransactionStatus(status);
		}
		//如果事务属性为null,不需要为方法使用事务
		else {
			if (logger.isTraceEnabled())
				logger.trace("Don't need to create transaction for [" + joinpointIdentification +
						"]: This method isn't transactional.");
		}
		//把当前创建的事务信息对象和线程绑定
		txInfo.bindToThread();
		return txInfo;
	} 


通过上面对TransactionAspectSupport事务切面支持类创建事务信息对象的源码分析,我们了解了在创建事务信息对象过程中创建事务状态,将创建的事务信息对象和当前线程资源绑定等基本的处理流程。在创建事务信息对象的方法中,事务处理器的tm.getTransaction(txAttr);是真正底层创建事务对象的方法,下面我们继续分析事务处理器创建事务对象的过程。


抽象事务管理器AbstractPlatformTransactionManager获取事务:

抽象事务管理器AbstractPlatformTransactionManager提供了创建事务的模板,这个模板会被具体的事务处理器所使用,抽象事务管理器根据事务属性配置和当前线程绑定信息对事务是否需要创建以及如何创建进行一些通用的处理,然后把事务创建的底层细节交给具体的事务处理器实现。抽象事务管理器创建事务的模板方法如下:

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
		//doGetTransaction()方法是抽象方法,具体的实现由具体的事务处理器提供
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();
		//如果没有配置事务属性,则使用默认的事务属性
		if (definition == null) {
			definition = new DefaultTransactionDefinition();
		}
		//检查当前线程是否存在事务,如果已存在事务,那么需要根据在事务属性中定义的事务传播属性来处理事务的产生
		if (isExistingTransaction(transaction)) {
			//处理已存在的事务的情况
			return handleExistingTransaction(definition, transaction, debugEnabled);
		}
		//检查事务属性中timeout超时属性设置是否合理
		if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
		}
		//对事务属性中配置的事务传播特性处理
		//如果事务传播特性配置的是mandatory,当前没有事务存在,抛出异常
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		//如果事务传播特性为required、required_new或nested
		else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
		    definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
			}
			//创建事务
			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 ex) {
				resume(null, suspendedResources);
				throw ex;
			}
			catch (Error err) {
				resume(null, suspendedResources);
				throw err;
			}
		}
		else {
		//创建空事务,针对supported类型的事务传播特性,激活和当前线程绑定的事务
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			//准备事务状态
			return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
		}
	}

//准备事务状态
protected final DefaultTransactionStatus prepareTransactionStatus(
			TransactionDefinition definition, Object transaction, boolean newTransaction,
			boolean newSynchronization, boolean debug, Object suspendedResources) {
		//创建事务状态
		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
		//准备事务状态
		prepareSynchronization(status, definition);
		return status;
	}
	//创建事务状态
	protected DefaultTransactionStatus newTransactionStatus(
			TransactionDefinition definition, Object transaction, boolean newTransaction,
			boolean newSynchronization, boolean debug, Object suspendedResources) {
		//判断是否是新事务,如果是新事务,则需要把事务属性存放到当前线程中
		boolean actualNewSynchronization = newSynchronization &&
		!TransactionSynchronizationManager.isSynchronizationActive();
		return new DefaultTransactionStatus(
				transaction, newTransaction, actualNewSynchronization,
				definition.isReadOnly(), debug, suspendedResources);
	}
	//初始化事务属性
	protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
		if (status.isNewSynchronization()) {
		//设置当前是否有活跃事务	TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
		//设置当前事务隔离级别	TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
					(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?
							definition.getIsolationLevel() : null);
			TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
	//设置当前事务名称	TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
			TransactionSynchronizationManager.initSynchronization();
		}
	}


抽象事务管理器AbstractPlatformTransactionManager处理已存在的事务:


对于新事务的处理相对比较简单,只需根据事务属性配置创建,同时将事务隔离级别等属性保存到事务绑定的线程资源中。而对于已存在的事务处理相对比较复杂一些,在抽象事务管理器AbstractPlatformTransactionManager中通过handleExistingTransaction方法来处理已存在的事务:

private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {
		//如果事务传播特性为:never,则抛出异常
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}
		//如果事务传播特性是not_supported,同时当前线程存在事务,则将事务挂起
		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);
		}
		//如果事务传播特性是required_new,则创建新事务,同时把当前线程中存在的
//事务挂起
		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 beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
			catch (Error beginErr) {
				resumeAfterBeginException(transaction, suspendedResources, beginErr);
				throw beginErr;
			}
		}
		//如果事务传播特性是nested嵌套事务
		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() + "]");
			}
			//如果允许使用savepoint保存点保存嵌套事务
			if (useSavepointForNestedTransaction()) {
				//为当前事务创建一个保存点
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				status.createAndHoldSavepoint();
				return status;
			}
			//如果不允许使用savepoint保存点保存嵌套事务
			else {
				//使用JTA的嵌套commit/rollback调用
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, null);
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
		}
		//对于事务传播特性为supported和required的处理
		if (debugEnabled) {
			logger.debug("Participating in existing transaction");
		}
		//校验已存在的事务,如果已有事务与事务属性配置不一致,则抛出异常
		if (isValidateExistingTransaction()) {
			//如果事务隔离级别不是默认隔离级别
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
				//获取当前事务的隔离级别
				Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
			//如果获取到的当前事务隔离级别为null获取不等于事务属性配置的隔离级别
				if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
					Constants isoConstants = DefaultTransactionDefinition.constants;
					throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));
				}
			}
			//如果事务不是只读
			if (!definition.isReadOnly()) {
				//如果当前已有事务是只读
				if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] is not marked as read-only but existing transaction is");
				}
			}
		}
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		//返回当前事务的执行状态
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

事务的挂起:

如果当前线程存在事务,但事务传播特性又要求开启新事务时,需要将已有的事务进行挂起,事务的挂起涉及线程与事务信息的保存,实现源码如下:

protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {
		//如果事务是激活的,且当前线程事务同步机制也是激活状态
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			//挂起当前线程中所有同步的事务
			List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
			try {
				Object suspendedResources = null;
				//把挂起事务的操作交由具体的事务处理器处理
				if (transaction != null) {
					suspendedResources = doSuspend(transaction);
				}
			//在线程中保存与事务处理有关的信息,并将线程里有关的线程局部变量重置
				String name = TransactionSynchronizationManager.getCurrentTransactionName();
//重置当前线程中事务相关的线程局部变量
TransactionSynchronizationManager.setCurrentTransactionName(null);
				boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
	TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
				Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
	TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
				boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
	TransactionSynchronizationManager.setActualTransactionActive(false);
				//将当前线程中事务相关信息保存
				return new SuspendedResourcesHolder(
						suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
			}
			//对事务挂起操作中产生异常和错误的处理
			catch (RuntimeException ex) {
				doResumeSynchronization(suspendedSynchronizations);
				throw ex;
			}
			catch (Error err) {
				doResumeSynchronization(suspendedSynchronizations);
				throw err;
			}
		}
		//如果事务是激活的,但是事务同步机制不是激活的,则只需要保存事务状态,不
//需要重置事务相关的线程局部变量
		else if (transaction != null) {
			Object suspendedResources = doSuspend(transaction);
			return new SuspendedResourcesHolder(suspendedResources);
		}
		//事务和事务同步机制都不是激活的,则不要想处理
		else {
			return null;
		}
	}



事务的提交:

当事务方法处理成功之后,需要将当前事务提交,将更改同步到数据库中,事务提交的入口调用在TransactionInterceptor的invoke方法事中时间,提交的实现源码如下:

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);
			return;
		}
		//如果事务没有被标记为回滚时提交,且事务状态时全局回滚
		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			//回滚处理
			processRollback(defStatus);
			//如果事务状态时新事务,或者在全局回滚时失败
			if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
			return;
		}
		//处理提交
		processCommit(defStatus);
	}

	//提交处理操作
	private void processCommit(DefaultTransactionStatus status) throws TransactionException {
		try {
			boolean beforeCompletionInvoked = false;
			try {
				//事务提交的准备工作,有具体的事务处理器完成
				prepareForCommit(status);
				triggerBeforeCommit(status);
				triggerBeforeCompletion(status);
				beforeCompletionInvoked = true;
				boolean globalRollbackOnly = false;
				//如果事务状态是新事务,或者全局回滚失败
				if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
					//设置事务全局回滚
					globalRollbackOnly = status.isGlobalRollbackOnly();
				}
				//嵌套事务处理
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Releasing transaction savepoint");
					}
					//释放挂起事务保存点
					status.releaseHeldSavepoint();
				}
				//如果当前事务是新事务
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction commit");
					}
					//调用具体事务处理器提交事务
					doCommit(status);
				}
				//如果事务被标记为全局回滚
				if (globalRollbackOnly) {
					throw new UnexpectedRollbackException(
							"Transaction silently rolled back because it has been marked as rollback-only");
				}
			}
			//提交过程中产生未预期的回滚异常,则回滚处理
			catch (UnexpectedRollbackException ex) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
				throw ex;
			}
			//对提交过程中产生的事务异常处理
			catch (TransactionException ex) {
				//如果回滚失败,则进行回滚异常处理
				if (isRollbackOnCommitFailure()) {
					doRollbackOnCommitException(status, ex);
				}
				else {
					triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				}
				throw ex;
			}
			//对提交过程中产生的异常处理
			catch (RuntimeException ex) {
				//如果不是在完成前调用的
				if (!beforeCompletionInvoked) {
					//触发完成前的回调方法
					triggerBeforeCompletion(status);
				}
				//进行回滚异常处理
				doRollbackOnCommitException(status, ex);
				throw ex;
			}
//对提交过程中产生的错误处理
			catch (Error err) {
				if (!beforeCompletionInvoked) {
					triggerBeforeCompletion(status);
				}
				doRollbackOnCommitException(status, err);
				throw err;
			}
			//触发提交之后的回调操作
			try {
				triggerAfterCommit(status);
			}
			finally {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
			}
		}
		//提交完成之后清除事务相关状态
		finally {
			cleanupAfterCompletion(status);
		}
	}

事务的回滚:

当在事务处理过程中产生异常,或者提交失败时,往往需要对数据库中已有的更改做回滚操作,即恢复到操作之前的状态,回滚的实现代码如下:

public final void rollback(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;
		//处理回滚的操作
		processRollback(defStatus);
	} 
//回滚操作
private void processRollback(DefaultTransactionStatus status) {
		try {
			try {
				//触发完成前的回调操作
				triggerBeforeCompletion(status);
				//嵌套事务回滚处理
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Rolling back transaction to savepoint");
					}
					//回滚挂起在保存点的事务
					status.rollbackToHeldSavepoint();
				}
				//当前事务中创建新事务的回滚操作
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction rollback");
					}
					//回滚处理,由具体的事务处理器实现
					doRollback(status);
				}
				//如果在当前事务中没有新建事务
				else if (status.hasTransaction()) {
					//如果当前事务状态为本地回滚,或全局回滚失败
					if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
						if (status.isDebug()) {
							logger.debug(
									"Participating transaction failed - marking existing transaction as rollback-only");
						}
						//设置当前事务状态为回滚
						doSetRollbackOnly(status);
					}
					//当前事务状态没有设置为本地回滚,且没有产生全局回滚失败,则
//由线程中的前一个事务来处理回滚,这个步骤任何处理
					else {
						if (status.isDebug()) {
							logger.debug(
									"Participating transaction failed - letting transaction originator decide on rollback");
						}
					}
				}
				//如果当前线程没有事务
				else {
					logger.debug("Should roll back transaction but cannot - no transaction available");
				}
			}
			//对回滚操作过程中的运行时异常和错误的处理
			catch (RuntimeException ex) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw ex;
			}
			catch (Error err) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw err;
			}
			//回滚操作完成后,触发回滚之后回调操作
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
		}
		//清除回滚之后事务状态信息
		finally {
			cleanupAfterCompletion(status);
		}
	}

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值