spring-事务源码解析(二)

8 篇文章 0 订阅
3 篇文章 0 订阅

我们在上一篇spring-事务源码解析(一)文章讲了spring如何对bean进行事务代理的检测和代理方式的选择,最终定位在了JdkDynamicAopProxy和ObjenesisCglibAopProxy两个代理类上,今天我们以JdkDynamicAopProxy为例,来看一下如何对bean进行事务代理和调用的。

/**
 * JdkDynamicAopProxy
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
	}
	// 获取目标类上的接口并且判断是否需要添加SpringProxy、Advised、DecoratingProxy接口
	Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
	// 判断目标类实现的接口是否定义了equals或hashCode方法
	// 在invoke方法调用时会对equals和hashCode方法做特殊处理
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	// 生成代理对象
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

/**
 * 获取目标类上的接口并且判断是否需要添加SpringProxy、Advised、DecoratingProxy接口
 * AopProxyUtils
 */
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
	Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
	if (specifiedInterfaces.length == 0) {
		// No user-specified interfaces: check whether target class is an interface.
		// 如果specifiedInterfaces为空,再次尝试获取接口
		Class<?> targetClass = advised.getTargetClass();
		if (targetClass != null) {
			if (targetClass.isInterface()) {
				advised.setInterfaces(targetClass);
			}
			else if (Proxy.isProxyClass(targetClass)) {
				advised.setInterfaces(targetClass.getInterfaces());
			}
			specifiedInterfaces = advised.getProxiedInterfaces();
		}
	}
	
	// 判断目标类是否实现了SpringProxy接口
	boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
	// 判断目标类是否实现了Advised接口
	boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
	// 判断目标类是否实现了DecoratingProxy接口
	boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
	int nonUserIfcCount = 0;
	if (addSpringProxy) {
		nonUserIfcCount++;
	}
	if (addAdvised) {
		nonUserIfcCount++;
	}
	if (addDecoratingProxy) {
		nonUserIfcCount++;
	}
	Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
	System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
	int index = specifiedInterfaces.length;
	if (addSpringProxy) {
		proxiedInterfaces[index] = SpringProxy.class;
		index++;
	}
	if (addAdvised) {
		proxiedInterfaces[index] = Advised.class;
		index++;
	}
	if (addDecoratingProxy) {
		proxiedInterfaces[index] = DecoratingProxy.class;
	}
	return proxiedInterfaces;
}

/**
 * 判断目标类实现的接口是否定义了equals或hashCode方法
 * JdkDynamicAopProxy
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}

上面创建了代理类,下面看一下代理逻辑的执行

/**
 * JdkDynamicAopProxy
 */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

	// 从advised中获取目标对象
	TargetSource targetSource = this.advised.targetSource;
	Object target = null;

	try {
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// 目标对象没有重写Object的equals方法,直接调用,不需要代理
			return equals(args[0]);
		}
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			// 目标对象没有重写Object的hashCode方法,直接调用,不需要代理
			return hashCode();
		}
		else if (method.getDeclaringClass() == DecoratingProxy.class) {
			// 如果是DecoratingProxy接口中的方法,返回代理类的终极目标类
			return AopProxyUtils.ultimateTargetClass(this.advised);
		}
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			// Spring AOP不会增强直接实现Advised接口的目标对象
			// 这里直接通过反射调用
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}

		Object retVal;

		// 是否需要在线程内共享代理对象
		if (this.advised.exposeProxy) {
			// Make invocation available if necessary.
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		}

		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);

		// 获取目标方法上的拦截器链
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

		if (chain.isEmpty()) {
			// 如果没有可用的拦截器,就直接通过反射在target上调用方法
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
		else {
			// 创建一个ReflectiveMethodInvocation,对AOP功能进行封装
			invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// 执行拦截器链
			retVal = invocation.proceed();
		}

		// Massage return value if necessary.
		Class<?> returnType = method.getReturnType();
		if (retVal != null && retVal == target &&
				returnType != Object.class && returnType.isInstance(proxy) &&
				!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
			// Special case: it returned "this" and the return type of the method
			// is type-compatible. Note that we can't help if the target sets
			// a reference to itself in another returned object.
			retVal = proxy;
		}
		else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
			throw new AopInvocationException(
					"Null return value from advice does not match primitive return type for: " + method);
		}
		return retVal;
	}
	finally {
		if (target != null && !targetSource.isStatic()) {
			// Must have come from TargetSource.
			targetSource.releaseTarget(target);
		}
		if (setProxyContext) {
			// Restore old proxy.
			AopContext.setCurrentProxy(oldProxy);
		}
	}
}

/**
 *  查询符合条件的拦截器
 * AdvisedSupport
 */
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
	MethodCacheKey cacheKey = new MethodCacheKey(method);
	// 先从缓存中获取
	List<Object> cached = this.methodCache.get(cacheKey);
	if (cached == null) {
		// 查询符合条件的拦截器
		cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
				this, method, targetClass);
		this.methodCache.put(cacheKey, cached);
	}
	return cached;
}

/**
 * 查询符合条件的拦截器
 * DefaultAdvisorChainFactory
 */
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
		Advised config, Method method, @Nullable Class<?> targetClass) {

	// This is somewhat tricky... We have to process introductions first,
	// but we need to preserve order in the ultimate list.
	List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
	AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

	// 遍历Advisor列表
	for (Advisor advisor : config.getAdvisors()) {
		if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
				// 获取advisor上的拦截器
				MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				// 检测目标方法和所在类是否符合pointcut
				if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
					// 如果符合,就添加拦截器
					if (mm.isRuntime()) {
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						interceptorList.addAll(Arrays.asList(interceptors));
					}
				}
			}
		}
		else if (advisor instanceof IntroductionAdvisor) {
			IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
			if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}
		else {
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			interceptorList.addAll(Arrays.asList(interceptors));
		}
	}
	return interceptorList;
}

/**
 * 执行拦截器链
 * ReflectiveMethodInvocation
 */
public Object proceed() throws Throwable {
	// 拦截器链是否执行完
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		// 反射调用目标方法
		return invokeJoinpoint();
	}

	// 从拦截器链中获取下一个拦截器
	Object interceptorOrInterceptionAdvice =
			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		// 动态匹配
		InterceptorAndDynamicMethodMatcher dm =
				(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
		// 判断方法以及所在类和定义的切点是否匹配
		if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
			return dm.interceptor.invoke(this);
		}
		else {
			// 如果上面匹配失败就跳过当前拦截器
			return proceed();
		}
	}
	else {
		// 如果是MethodInterceptor,就直接调用
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

/**
 * TransactionInterceptor
 */
public Object invoke(final MethodInvocation invocation) throws Throwable {
	// Work out the target class: may be {@code null}.
	// The TransactionAttributeSource should be passed the target class
	// as well as the method, which may be from an interface.
	Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

	// Adapt to TransactionAspectSupport's invokeWithinTransaction...
	return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}

/**
 * TransactionInterceptor(TransactionAspectSupport)
 */
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
		final InvocationCallback invocation) throws Throwable {
	// 获取对应事务属性,如果事务属性为空,则目标方法不存在事务(检测@Transactional注解)
	TransactionAttributeSource tas = getTransactionAttributeSource();
	final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
	// 根据事务的属性获取spring容器中的PlatformTransactionManager(spring事务管理器的顶级接口)
	// 一般这里是DataSourceTransactionManager
	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
	// 目标方法唯一标识(包.类.方法)
	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
	// 如果txAttr为空或tm不是CallbackPreferringPlatformTransactionManager,则执行目标增强
	if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		// 判断是否需要创建一个事务,根据事务传播行为,做出相应的判断,下面会进一步分析
		TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
		Object retVal = null;
		try {
			// 这是一个around advice
			// 执行下一个拦截器逻辑
			retVal = invocation.proceedWithInvocation();
		}
		catch (Throwable ex) {
			// 捕获异常,判断对该异常是否需要回滚,或者是直接提交事务
			completeTransactionAfterThrowing(txInfo, ex);
			throw ex;
		}
		finally {
			// 重置oldTransactionInfo
			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;
		}
	}
}

/**
 * TransactionInterceptor(TransactionAspectSupport)
 */
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
		@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

	// If no name specified, apply method identification as transaction name.
	if (txAttr != null && txAttr.getName() == null) {
		txAttr = new DelegatingTransactionAttribute(txAttr) {
			@Override
			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);
}

/**
 * @Transactional(propagation=Propagation.REQUIRED)
   *   如果有事务,就加入事务,没有的话就新建一个(默认)
 * @Transactional(propagation=Propagation.NOT_SUPPORTED)
   *    以非事务方式执行,如果当前存在事务,就把当前事务挂起
 * @Transactional(propagation=Propagation.REQUIRES_NEW)
   *    不管是否存在事务,都创建一个新的事务,原来的事务挂起,新的执行完毕,继续执行老的事务
 * @Transactional(propagation=Propagation.MANDATORY)
    *   使用当前的事务,如果当前没有事务,就抛异常
 * @Transactional(propagation=Propagation.NEVER)
   *    以非事务方式执行,如果当前存在事务,则抛异常(与MANDATORY相反)
 * @Transactional(propagation=Propagation.SUPPORTS)
    *   支持当前事务,如果当前没有事务,就以非事务方式执行
 * @Transactional(propagation=Propagation.NESTED)
    *   如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则执行与REQUIRED类似的操作
 * 
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
	// 调用PlatformTransactionManager(其实是DataSourceTransactionManager)的getTransaction方法
	// 来获取线程共享的TransactionStatus对象(如果之前已经开启过事务)
	Object transaction = doGetTransaction();

	// Cache debug flag to avoid repeated checks.
	boolean debugEnabled = logger.isDebugEnabled();

	if (definition == null) {
		// Use defaults if no transaction definition given.
		definition = new DefaultTransactionDefinition();
	}

	// 判断当前线程是否已经存在事务
	if (isExistingTransaction(transaction)) {
		// 如果存在,就根据传播方式进一步处理
		return handleExistingTransaction(definition, transaction, debugEnabled);
	}

	// Check definition settings for new transaction.
	if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
		throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
	}

	// 如果是PROPAGATION_MANDATORY(必须在一个已有的事务中执行)传播方式,就抛出异常
	if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
		throw new IllegalTransactionStateException(
				"No existing transaction found for transaction marked with propagation 'mandatory'");
	}
	// 如果是以下3中传播方式,就创建一个新的事务
	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);
                        // 创建新事务时,将newTransaction设为true, 将newSynchronization设为true
			DefaultTransactionStatus status = newTransactionStatus(
					definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
			// 开启新事务,并绑定到当前线程上(第一次获取)
			doBegin(transaction, definition);
			prepareSynchronization(status, definition);
			return status;
		}
		catch (RuntimeException | Error ex) {
			resume(null, suspendedResources);
			throw ex;
		}
	}
	else {
		// Create "empty" transaction: no actual transaction, but potentially synchronization.
		if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
			logger.warn("Custom isolation level specified but no actual transaction initiated; " +
					"isolation level will effectively be ignored: " + definition);
		}
		boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
		return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
	}
}

/**
 * 创建事务对象,从当前线程上获取事务,绑定到该对象上
 * DataSourceTransactionManager
 */
protected Object doGetTransaction() {
	DataSourceTransactionObject txObject = new DataSourceTransactionObject();
	txObject.setSavepointAllowed(isNestedTransactionAllowed());
	ConnectionHolder conHolder =
			(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
        // 从线程上获取connectionHolder,newConnectionHolder=false
	txObject.setConnectionHolder(conHolder, false);
	return txObject;
}

/**
 * DataSourceTransactionManager
 */
protected boolean isExistingTransaction(Object transaction) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
	// 如果是第一次开启事务这里必然是false,否则返回true
	return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}


/**
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
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()) {
			// Create savepoint within existing Spring-managed transaction,
			// through the SavepointManager API implemented by TransactionStatus.
			// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
			DefaultTransactionStatus status =
					prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
			status.createAndHoldSavepoint();
			return status;
		}
		else {
			// Nested transaction through nested begin and commit/rollback calls.
			// Usually only for JTA: Spring synchronization might get activated here
			// in case of a pre-existing JTA transaction.
			boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
			DefaultTransactionStatus status = newTransactionStatus(
					definition, transaction, true, newSynchronization, debugEnabled, null);
			doBegin(transaction, definition);
			prepareSynchronization(status, definition);
			return status;
		}
	}

	// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
	if (debugEnabled) {
		logger.debug("Participating in existing transaction");
	}
	if (isValidateExistingTransaction()) {
		if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
			Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
			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);
         // 事务已存在时,将newTransaction设为false, 将newSynchronization设为false
	return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

/**
 * DataSourceTransactionManager
 */
protected void doBegin(Object transaction, TransactionDefinition definition) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
	Connection con = null;

	try {
		// 事务对象上没有连接,就获取一个新的
		if (!txObject.hasConnectionHolder() ||
				txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
			// 从dataSource中获取一个Connection
			Connection newCon = obtainDataSource().getConnection();
			if (logger.isDebugEnabled()) {
				logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
			}
			// 为当前Transaction设置ConnectionHolder,并且设置newConnectionHolder为true
			txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
		}
		// 设置ConnectionHolder的SynchronizedWithTransaction属性为true
		txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
		con = txObject.getConnectionHolder().getConnection();

		// 对连接进行只读和隔离级别设置
		Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
		txObject.setPreviousIsolationLevel(previousIsolationLevel);

		// 将事务设置为手动提交
		if (con.getAutoCommit()) {
			txObject.setMustRestoreAutoCommit(true);
			if (logger.isDebugEnabled()) {
				logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
			}
			con.setAutoCommit(false);
		}

		prepareTransactionalConnection(con, definition);
		// 设置ConnectionHolder的TransactionActive属性为true
		txObject.getConnectionHolder().setTransactionActive(true);

		// 超时时间设置
		int timeout = determineTimeout(definition);
		if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
			txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
		}

		// 如果是新连接,就绑定到当前线程(这里是重点,为什么在我们自己的方法里面可以获取这里的连接,就是通过这里的线程共享)
		if (txObject.isNewConnectionHolder()) {
			TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
		}
	}

	catch (Throwable ex) {
		if (txObject.isNewConnectionHolder()) {
			DataSourceUtils.releaseConnection(con, obtainDataSource());
			txObject.setConnectionHolder(null, false);
		}
		throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
	}
}

上面的代理逻辑就是从线程上获取连接(第一次是创建),并进行配置(自动提交,事务隔离级别等),让后再绑定到线程上,最后再执行用户自己的逻辑,最后判断是否需要回滚事务还是提交事务,下面来看一下用户是如果获取上面创建的数据库连接的,以spring jdbcTemplate为例

/**
 * 声明式事务,对Exception进行回滚
 */
@Transactional(rollbackFor=Exception.class)
@Override
public void create(Long id,String cityName) {
	jdbcTemplate.update("insert into city(id,province_id,city_name) values(?,1,?)", id,cityName);
	// 在这里故意抛出一个异常,迫使事务回滚
	throw new IllegalArgumentException();
}

/**
 * JdbcTemplate
 */
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
		throws DataAccessException {

	Assert.notNull(psc, "PreparedStatementCreator must not be null");
	Assert.notNull(action, "Callback object must not be null");
	if (logger.isDebugEnabled()) {
		String sql = getSql(psc);
		logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
	}

	// 重点看看这里是如何获取数据库连接的,DataSource是在JdbcTemplate初始化时就注入的
	Connection con = DataSourceUtils.getConnection(obtainDataSource());
	PreparedStatement ps = null;
	try {
		ps = psc.createPreparedStatement(con);
		applyStatementSettings(ps);
		T result = action.doInPreparedStatement(ps);
		handleWarnings(ps);
		return result;
	}
	catch (SQLException ex) {
		// Release Connection early, to avoid potential connection pool deadlock
		// in the case when the exception translator hasn't been initialized yet.
		if (psc instanceof ParameterDisposer) {
			((ParameterDisposer) psc).cleanupParameters();
		}
		String sql = getSql(psc);
		JdbcUtils.closeStatement(ps);
		ps = null;
		DataSourceUtils.releaseConnection(con, getDataSource());
		con = null;
		throw translateException("PreparedStatementCallback", sql, ex);
	}
	finally {
		if (psc instanceof ParameterDisposer) {
			((ParameterDisposer) psc).cleanupParameters();
		}
		JdbcUtils.closeStatement(ps);
		DataSourceUtils.releaseConnection(con, getDataSource());
	}
}

/**
 * 获取数据库连接
 * 1.先从线程上获取
 * 2.线程上获取不到,就创建一个新连接
 * DataSourceUtils
 */
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
	Assert.notNull(dataSource, "No DataSource specified");

	// 获取线程上绑定的ConnectionHolder(还记得上面代理中在doBegin方法中是如何将这个对象绑定到线程上的吗?)
	ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
	if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
		conHolder.requested();
		if (!conHolder.hasConnection()) {
			logger.debug("Fetching resumed JDBC Connection from DataSource");
			conHolder.setConnection(fetchConnection(dataSource));
		}
		return conHolder.getConnection();
	}
	// 如果线程上没有过去到,就去重新获取一个连接
	Connection con = fetchConnection(dataSource);

	if (TransactionSynchronizationManager.isSynchronizationActive()) {
		logger.debug("Registering transaction synchronization for JDBC Connection");
		// Use same Connection for further JDBC actions within the transaction.
		// Thread-bound object will get removed by synchronization at transaction completion.
		ConnectionHolder holderToUse = conHolder;
		if (holderToUse == null) {
			holderToUse = new ConnectionHolder(con);
		}
		else {
			holderToUse.setConnection(con);
		}
		holderToUse.requested();
		TransactionSynchronizationManager.registerSynchronization(
				new ConnectionSynchronization(holderToUse, dataSource));
		holderToUse.setSynchronizedWithTransaction(true);
		if (holderToUse != conHolder) {
			// 重新绑定到线程
			TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
		}
	}

	return con;
}

上面就获取到了数据库连接,后面就看你如何使用这个连接了,下面看一下事务是如果提交的

/**
 * TransactionInterceptor(TransactionAspectSupport)
 * 提交事务
 */
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());
	}
}

/**
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
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);
}

/**
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
	try {
		boolean beforeCompletionInvoked = false;

		try {
			boolean unexpectedRollback = false;
			prepareForCommit(status);
			// 触发synchronization.beforeCommit方法
			triggerBeforeCommit(status);
			// 触发synchronization.beforeCompletion方法
			triggerBeforeCompletion(status);
			beforeCompletionInvoked = true;

			// 判断是否有savePoint,如果有,说明此时的事务是嵌套事务NESTED
			// 这个事务外面还有事务,这里不提交,只是释放保存点
			if (status.hasSavepoint()) {
				if (status.isDebug()) {
					logger.debug("Releasing transaction savepoint");
				}
				unexpectedRollback = status.isGlobalRollbackOnly();
				// 不提交事务,仅仅是释放保存点
				status.releaseHeldSavepoint();
			}
			// 判断是否是新事务
			else if (status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.debug("Initiating transaction commit");
				}
				unexpectedRollback = status.isGlobalRollbackOnly();
				// 这里才真正去提交
				doCommit(status);
			}
			else if (isFailEarlyOnGlobalRollbackOnly()) {
				unexpectedRollback = status.isGlobalRollbackOnly();
			}

			// Throw UnexpectedRollbackException if we have a global rollback-only
			// marker but still didn't get a corresponding exception from commit.
			if (unexpectedRollback) {
				throw new UnexpectedRollbackException(
						"Transaction silently rolled back because it has been marked as rollback-only");
			}
			// 如果是子事务、PROPAGATION_SUPPORTS、PROPAGATION_REQUIRED、PROPAGATION_MANDATORY这几种状态是旧事务,
			// 提交的时候将什么都不做,因为它们是运行在外层事务当中,如果子事务没有回滚,将由外层事务一次性提交
		}
		catch (UnexpectedRollbackException ex) {
			// can only be caused by doCommit
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
			throw ex;
		}
		catch (TransactionException ex) {
			// can only be caused by doCommit
			if (isRollbackOnCommitFailure()) {
				doRollbackOnCommitException(status, ex);
			}
			else {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
			}
			throw ex;
		}
		catch (RuntimeException | Error ex) {
			if (!beforeCompletionInvoked) {
				triggerBeforeCompletion(status);
			}
			doRollbackOnCommitException(status, ex);
			throw ex;
		}

		try {
			// 触发synchronization.afterCommit方法
			triggerAfterCommit(status);
		}
		finally {
			// 触发synchronization.afterCompletion方法
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
		}

	}
	finally {
		// 重置状态,释放连接,唤醒挂起的事务
		cleanupAfterCompletion(status);
	}
	
	/**
	 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
	 */
	private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		status.setCompleted();
		// 如果newSynchronization为true,则重置TransactionSynchronizationManager相关状态
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clear();
		}
		// 如果newSynchronization为true,释放相关资源
		// 1. 解绑线程上的connectionHolder
		// 2.重置数据库连接(autoCommit,isolationLevel),释放连接
		// 3.重置connectionHolder上相关状态
		if (status.isNewTransaction()) {
			doCleanupAfterCompletion(status.getTransaction());
		}
		// 将之前挂起线程唤醒
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction after completion of inner transaction");
			}
			Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
			resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}
	
	/**
	 * TransactionSynchronizationManager
	 */
	public static void clear() {
		synchronizations.remove();
		currentTransactionName.remove();
		currentTransactionReadOnly.remove();
		currentTransactionIsolationLevel.remove();
		actualTransactionActive.remove();
	}
	
	/**
	 * DataSourceTransactionManager
	 */
	protected void doCleanupAfterCompletion(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;

		// 如果是新建事务,将cononectionHolder从当前线程中解除绑定
		if (txObject.isNewConnectionHolder()) {
			TransactionSynchronizationManager.unbindResource(obtainDataSource());
		}

		Connection con = txObject.getConnectionHolder().getConnection();
		try {
			// 恢复数据库会话事务自动提交属性
			if (txObject.isMustRestoreAutoCommit()) {
				con.setAutoCommit(true);
			}
			// 重置数据库连接
			DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
		}
		catch (Throwable ex) {
			logger.debug("Could not reset JDBC Connection after transaction", ex);
		}

		// 如果是新建事务,则将数据库连接释放回连接池
		if (txObject.isNewConnectionHolder()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
			}
			DataSourceUtils.releaseConnection(con, this.dataSource);
		}
		// 清理connectionHolder上相关资源
		txObject.getConnectionHolder().clear();
	}
}

/**
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
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
 */
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
	TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}

/**
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
private void doResumeSynchronization(List<TransactionSynchronization> suspendedSynchronizations) {
	TransactionSynchronizationManager.initSynchronization();
	for (TransactionSynchronization synchronization : suspendedSynchronizations) {
		synchronization.resume();
		TransactionSynchronizationManager.registerSynchronization(synchronization);
	}
}

上面可以看出,只对新建事务执行提交操作,内嵌事务(NESTED)执行释放保存点操作,下面看一下事务是如何回滚的:

/**
 * commit或rollback
 * TransactionInterceptor(TransactionAspectSupport)
 */
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
	if (txInfo != null && txInfo.getTransactionStatus() != null) {
		if (logger.isTraceEnabled()) {
			logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
					"] after exception: " + ex);
		}
		// 判断当前异常是否允许回滚
		if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
			try {
				txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
			}
			catch (TransactionSystemException ex2) {
				logger.error("Application exception overridden by rollback exception", ex);
				ex2.initApplicationException(ex);
				throw ex2;
			}
			catch (RuntimeException | Error ex2) {
				logger.error("Application exception overridden by rollback exception", ex);
				throw ex2;
			}
		}
		else {
			// We don't roll back on this exception.
			// Will still roll back if TransactionStatus.isRollbackOnly() is true.
			try {
				txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
			}
			catch (TransactionSystemException ex2) {
				logger.error("Application exception overridden by commit exception", ex);
				ex2.initApplicationException(ex);
				throw ex2;
			}
			catch (RuntimeException | Error ex2) {
				logger.error("Application exception overridden by commit exception", ex);
				throw ex2;
			}
		}
	}
}

/**
 * rollback
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
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, false);
}

/**
 * rollback
 * DataSourceTransactionManager(AbstractPlatformTransactionManager)
 */
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
	try {
		boolean unexpectedRollback = unexpected;

		try {
			// 触发synchronization.beforeCompletion方法
			triggerBeforeCompletion(status);

			// 如果有保存点(NESTED),只回滚保存点
			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 {
				// Participating in larger transaction
				if (status.hasTransaction()) {
					if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
						if (status.isDebug()) {
							logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
						}
                                                // 标记当前事务为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");
				}
				// Unexpected rollback only matters here if we're asked to fail early
				if (!isFailEarlyOnGlobalRollbackOnly()) {
					unexpectedRollback = false;
				}
			}
		}
		catch (RuntimeException | Error ex) {
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
			throw ex;
		}
		// 触发synchronization.afterCompletion方法
		triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

		// Raise UnexpectedRollbackException if we had a global rollback-only marker
		if (unexpectedRollback) {
			throw new UnexpectedRollbackException(
					"Transaction rolled back because it has been marked as rollback-only");
		}
	}
	finally {
		// 重置状态,释放连接,唤醒挂起的事务
		cleanupAfterCompletion(status);
	}
}

/**
 * DataSourceTransactionManager
 */
protected void doRollback(DefaultTransactionStatus status) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
	Connection con = txObject.getConnectionHolder().getConnection();
	if (status.isDebug()) {
		logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
	}
	try {
		// 回滚事务
		con.rollback();
	}
	catch (SQLException ex) {
		throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
	}
}

从上面实现可知,只对新建事务执行回滚操作,内嵌事务(NESTED)执行回滚保存点操作,至此,spring的事务代理就解析完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值