Spring 事务-05-事务基类-TransactionAspectSupport

馋奶兔 提交于 2020-02-27 04:20:53

1 用途

事务方面的基类,如{@link TransactionInterceptor}或AspectJ方面。

这使得底层的Spring事务基础结构可以很容易地用于为任何方面系统实现方面。

子类负责以正确的顺序调用该类中的方法。

注意:这个类不能实现Serializable,因为它是AspectJ方面的基类(不允许实现Serializable)!

2 类图

3 类核心方法

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.interceptor.*;
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Properties;
import java.util.concurrent.ConcurrentMap;

/**
 * 事务方面的基类,如{@link TransactionInterceptor}或AspectJ方面。
 * 这使得底层的Spring事务基础结构可以很容易地用于为任何方面系统实现方面。
 *
 * 注意:这个类不能实现Serializable,因为它是AspectJ方面的基类(不允许实现Serializable)!
 *
 * <p> 子类负责以正确的顺序调用该类中的方法。
 *
 * <p>
 * 如果{@code TransactionAttribute}中没有指定事务名,
 * 则公开的名称将是{@code 完全限定类名 +  "." + 方法名}(默认)。
 *
 * <p>
 * 使用策略设计模式。
 * {@code PlatformTransactionManager}实现将执行实际的事务管理,{@code TransactionAttributeSource}用于确定事务定义。
 *
 * <p>
 * 如果事务方面的{@code PlatformTransactionManager}和{@code TransactionAttributeSource}是可序列化的,
 * 则事务方面是可序列化的。
 *
 * @since 1.1
 * @see #setTransactionManager
 * @see #setTransactionAttributes
 * @see #setTransactionAttributeSource
 */
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {

	@Nullable
	private String transactionManagerBeanName;

	@Nullable
	private PlatformTransactionManager transactionManager;

	@Nullable
	private TransactionAttributeSource transactionAttributeSource;

	/**
	 * 用于基于around-advice的子类的常规委托,委托给该类上的其他几个模板方法。
	 * 能够处理{@link CallbackPreferringPlatformTransactionManager}以及常规{@link PlatformTransactionManager}实现。
	 *
	 * @param method 被调用的方法
	 * @param targetClass 我们调用方法的目标类
	 * @param invocation 用于继续目标调用的回调
	 * @return 方法的返回值(如果有)
	 * @throws Throwable propagated from the target invocation
	 */
	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// 如果事务属性为空,则该方法是非事务性的。
		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)) {
			// 使用getTransaction和提交/回滚调用的标准事务划分。
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// 这是一个around建议:调用链中的下一个拦截器。
				// 这通常会导致调用目标对象。
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// 目标调用异常
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// 清理资源
				cleanupTransactionInfo(txInfo);
			}
			// 目标调用正确,提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// 它是一个CallbackPreferringPlatformTransactionManager:传入一个TransactionCallback。
			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);
					}
				});

				// 检查结果状态:它可能指示一个可抛出的重新抛出。
				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;
			}
		}
	}

}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!