六Spring事务--2事务抽象类
六Spring事务--2事务抽象类
6.2 Spring事务重要组件类
6.2.1 事务抽象类
事务抽象类之间的构建关系,最终需要获得transactionInfo对象,该对象位于TransactionInterceptor的父类TransactionAspectSupport的内部类中,其包装了事务的所有信息,用于在执行事务方法时,拦截到事务方法,通过获取TransactionInfo,执行事务相关的操作。
可知:在createTransactionIfNecessary创建事务的方法中,需要把TransactionAttribute最终转化为TransactionInfo。
事务组件类 | 简述 |
---|---|
TransactionDefinition | 只记录事务的隔离级别、传播机制等 |
TransactionAttribute | 继承自TD,多了判定异常是否rollback和限定词getQualifier |
TransactionStatus | 封装connection对象,以及当前事务的status状态 |
TransactionInfo | 前三个组件类的总和,以及事务管理器、需要实物增强的方法名joinpointIdentification |
6.2.1.1 TransactionDefinition(I)
负责transaction的定义,包括隔离级别、事务名称、传播行为、是否只读、timeout。
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);
}

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--注解解析器
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点等等。事务的执行状态首先在这个类内设置标志位,在完成事务时,再进行对应的处理。

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;
}