六Spring事务--2事务抽象类

六Spring事务--2事务抽象类

6.2 Spring事务重要组件类

6.2.1 事务抽象类

事务抽象类之间的构建关系,最终需要获得transactionInfo对象,该对象位于TransactionInterceptor的父类TransactionAspectSupport的内部类中,其包装了事务的所有信息,用于在执行事务方法时,拦截到事务方法,通过获取TransactionInfo,执行事务相关的操作。

可知:在createTransactionIfNecessary创建事务的方法中,需要把TransactionAttribute最终转化为TransactionInfo。

image-20220516161351148

事务组件类 简述
TransactionDefinition 只记录事务的隔离级别、传播机制等
TransactionAttribute 继承自TD,多了判定异常是否rollback和限定词getQualifier
TransactionStatus 封装connection对象,以及当前事务的status状态
TransactionInfo 前三个组件类的总和,以及事务管理器、需要实物增强的方法名joinpointIdentification

6.2.1.1 TransactionDefinition(I)

负责transaction的定义,包括隔离级别、事务名称、传播行为、是否只读、timeout。

image-20220514192338203

6.2.1.1.1 TransactionAttribute

为TransactionDefinition添加rollbackOn的规范化方法;

public interface TransactionAttribute extends TransactionDefinition {
     //返回和这个事务属性相关的qualifier值。被用来选择一个相关的transaction manager处理这个特定的transaction
	String getQualifier();
     //是否应该在指定的exception上回滚
	boolean rollbackOn(Throwable ex);
}

6.2.1.2 TransactionAttributeSource

用来获取事务属性TransactionAttribute的source源。

public interface TransactionAttributeSource {
     //确定当前targetclass是否是TransactionAttributeSource元数据格式的事务属性的候选者
     //false:表示该类在类或者方法级别没有事务属性。不会遍历给定类targetclass的方法来执行getTransactionAttribute
     //true:表示该类在类或者方法级别有事务属性。要针对给定类targetclass的每个方法单独进行完全自省
	default boolean isCandidateClass(Class<?> targetClass) {
		return true;
	}

     //返回给定方法的事务属性(如果方法非事务方法,返回null)
	@Nullable
	TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass);
}
image-20220509140202004
6.2.1.2.1 AbstractFallbackTransactionAttributeSource

抽象类,抽象创建TransactionAttribute的通用逻辑,具体实现方法,交由子类实现。

public abstract class AbstractFallbackTransactionAttributeSource
		implements TransactionAttributeSource, EmbeddedValueResolverAware {

  //MethodClassKey(method, targetClass)为key,TransactionAttribute为value
	private final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<>(1024);

     //返回给定方法的事务属性(如果方法非事务方法,返回null)
  @Override
	@Nullable
	public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// 首先,看是否有缓存
		Object cacheKey = getCacheKey(method, targetClass);
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				return cached;
			}
		}
    //如果没有缓存
		else {
			// 解决对应targetclass上method的事务属性---见下面代码
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			if (txAttr == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
        //事务拦截点方法的字符串信息
				String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
				if (txAttr instanceof DefaultTransactionAttribute) {
					DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
          //设置事务属性的拦截点描述信息--method的字符串信息
					dta.setDescriptor(methodIdentification);
					dta.resolveAttributeStrings(this.embeddedValueResolver);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
        //存入当前缓存
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}
  
  //解析事务属性的模板方法(通用方法框架,具体实现交给子类实现)
  protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// Don't allow non-public methods, as configured.
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

    //给定的method,可能是interface的方法对象,而我们需要获取目标对象targetclass内的方法对象specificMethod
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

/**…………………………………………………………………………1 method位于targetclass--specificMethod………………………………………………………… */
		// 首先,尝试从specificMethod中获取(就是从targetclass的方法上)
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// 其次,从specificMethod的声明类上(就是targetclass上获取)
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}

/**……………………………………………………………………………………2 method位于targetclass父类上…………………………………………………………………………………… */
    //如果specificMethod != method,表示method不在targetclass上,而在父类上
		if (specificMethod != method) {
			// 从method的原始方法上获取事务属性.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			// 从method所在的原本的类上,获取事务属性
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}

上述定义了根据给定的method和targetclass获取事务属性的通用逻辑。其中,在解析事务属性方法中computeTransactionAttribute,根据传入的参数method和targetclass,method可能是targetclass内的方法,也可能是targetclass父类的方法。根据这两种情况,分别来解析属性。

1 method位于targetclass--specificMethod

2 method位于targetclass父类上

具体的解析方法findTransactionAttribute,交给子类去解决。

6.2.1.2.2 AnnotationTransactionAttributeSource

这个事务属性源,是全局的属性源,记录spring中所有的事务方法上的事务信息,父类中Map<Object, TransactionAttribute> attributeCache记录所有class-method以及对应的TransactionAttribute,提供给TransactionManager使用。

public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
		implements Serializable {
		
  //是否只支持public方法为事务方法
	private final boolean publicMethodsOnly;
	//存储解析器集合---这个解析器负责解析@Transactional注释,创建TransactionAttribute
	private final Set<TransactionAnnotationParser> annotationParsers;

  //
@Override
	public boolean isCandidateClass(Class<?> targetClass) {
    //遍历当前缓存的所有注解解析器,看是否有支持当前类targetclass解析的parser
		for (TransactionAnnotationParser parser : this.annotationParsers) {
      //用特定的注释解析器parser,判断当前class是否是parser可以解析成TransactionAttribute
			if (parser.isCandidateClass(targetClass)) {
				return true;
			}
		}
		return false;
	}

	@Override
	@Nullable
	protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
		return determineTransactionAttribute(clazz);
	}

	@Override
	@Nullable
	protected TransactionAttribute findTransactionAttribute(Method method) {
		return determineTransactionAttribute(method);
	}

  //将注解的元素(被注解的类或者方法对象),转换为TransactionAttribute对象
	@Nullable
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		for (TransactionAnnotationParser parser : this.annotationParsers) {
      //将element解析为TransactionAttribute
			TransactionAttribute attr = parser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}
6.2.1.2.3 TransactionAnnotationParser--注解解析器

image-20221120111027931

public interface TransactionAnnotationParser {

	/**
	 决定当前类,是否是注解模式@transactional的候选类。
	 如果返回false,不再遍历targetclass上的method对象以及执行parseTransactionAnnotation解析;
	 如果返回true,表示当前类被事务增强,需要执行parseTransactionAnnotation,遍历每个method,获取事务属性
	 */
	default boolean isCandidateClass(Class<?> targetClass) {
		return true;
	}

	/**基于当前parser的注解类型,解析给定class、method的信息构建为TransactionAttribure对象*/
	@Nullable
	TransactionAttribute parseTransactionAnnotation(AnnotatedElement element);
}
6.2.1.2.3.1 SpringTransactionAnnotationParser
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

  //判断当前targetClass,是否被@Transactional注解
	@Override
	public boolean isCandidateClass(Class<?> targetClass) {
    //这个方法,判断targetclass是否承载指定注释@Transactional的候选类(注解在类型、方法或字段的级别)
		return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
	}

	@Override
	@Nullable
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    //从注解@Transactional上,获取注解的属性的信息
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}

	public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
		return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
	}

  //解析注解的属性信息,并构建和转换为事务属性TransactionAttribute
	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    //创建RuleBasedTransactionAttribute事务属性,并在后续根据注解属性,设置入事务属性
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());

		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		String timeoutString = attributes.getString("timeoutString");
		Assert.isTrue(!StringUtils.hasText(timeoutString) || rbta.getTimeout() < 0,
				"Specify 'timeout' or 'timeoutString', not both");
		rbta.setTimeoutString(timeoutString);

		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));
		rbta.setLabels(Arrays.asList(attributes.getStringArray("label")));

		List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}

6.2.1.3 TransactionStatus

事务状态类。记录当前事务的执行状态,如是否是rollbackonly、是否是newTransaction、是否有savepoint点等等。事务的执行状态首先在这个类内设置标志位,在完成事务时,再进行对应的处理。

image-20220515235435397
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
	boolean hasSavepoint();
	@Override
	void flush();
}
6.2.1.3.1 AbstractTransactionStatus
public abstract class AbstractTransactionStatus implements TransactionStatus {

	private boolean rollbackOnly = false;

	private boolean completed = false;

	@Nullable
	private Object savepoint;
}
6.2.1.3.2 DefaultTransactionStatus

只有newTransaction为true时,spring才会做实际的提交或回滚,这里是一个很重要的点。很多嵌套事务的坑,都是这里没有理解清楚。

public class DefaultTransactionStatus extends AbstractTransactionStatus {

	@Nullable
	private final Object transaction;

	private final boolean newTransaction;

	private final boolean newSynchronization;

	private final boolean readOnly;

	private final boolean debug;

	@Nullable
	private final Object suspendedResources;

6.2.1.4 TransactionInfo(TAS内部类)

该类作为TransactionAspectSupport的内部类,执行——事务所有信息、状态的包装类。

用以让TransactionInterceptor调用当前transaction的相关信息及方法。

	protected static final class TransactionInfo {
    //事务管理器
		private final PlatformTransactionManager transactionManager;
    //info内包含attribute和status属性
		private final TransactionAttribute transactionAttribute;
		private TransactionStatus transactionStatus;
		private TransactionInfo oldTransactionInfo;
     //执行事务点的方法名
		private final String joinpointIdentification;

		public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,
				@Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {
			this.transactionManager = transactionManager;
			this.transactionAttribute = transactionAttribute;
			this.joinpointIdentification = joinpointIdentification;
		}
		//是否有事务(通过是否存在TransactionStatus)
		public boolean hasTransaction() {
			return (this.transactionStatus != null);
		}

          //暴露及绑定当前transactionInfo到线程
		private void bindToThread() {
          //private static final ThreadLocal<TransactionInfo> transactionInfoHolder 
          //该属性是TransactionAspectSupport的属性,线程共享变量
			this.oldTransactionInfo = transactionInfoHolder.get();
			transactionInfoHolder.set(this);
		}

		private void restoreThreadLocalStatus() {
			// Use stack to restore old transaction TransactionInfo.
			// Will be null if none was set.
			transactionInfoHolder.set(this.oldTransactionInfo);
		}

	}

6.2.2 辅助组件类

6.2.2.1 ConnectionHolder

public class ConnectionHolder extends ResourceHolderSupport {
	//savepoint名字的前缀
	public static final String SAVEPOINT_NAME_PREFIX = "SAVEPOINT_";

	private ConnectionHandle connectionHandle;
	private Connection currentConnection;
     //当前事务是否活跃状态
	private boolean transactionActive = false;
	private Boolean savepointsSupported;
	private int savepointCounter = 0;

connection持有类。

6.2.2.2 SavepointManager

挂起事务,并创建的保存点savepoint。savepointManager负责保存点的管理。

public interface SavepointManager {

	Object createSavepoint() throws TransactionException;
	void rollbackToSavepoint(Object savepoint) throws TransactionException;
	void releaseSavepoint(Object savepoint) throws TransactionException;

}
posted @ 2023-03-10 17:17  LeasonXue  阅读(293)  评论(0)    收藏  举报