Spring5.X 事务相关类介绍

1、创建事务代理流程

(1) 注入类型为TransactionAttributeSource的Bean
对于方法事务属性获取规则:如果方法中存在事务属性,则使用方法上的事物属性,否则使用方法所在的类上的属性;如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么再搜寻接口中的方法,再没有的话,最后尝试搜寻接口的类上面的声明。
(2) 注入类型为TransactionInterceptor的Bean
(3) 注入类型为BeanFactoryTransactionAttributeSourceAdvisor的Bean,pointcunt是TransactionAttributeSourcePointcut用到了TransactionAttributeSource来匹配是否需要为指定Bean创建事物代理,匹配规则是判断方法是是否有事物注解(具体事物注解用Spring/JTA/EJB视情况而定)。
(4) 注入类型为InfrastructureAdvisorAutoProxyCreator的Bean,是一个BeanPostProcessor,基于BeanFactoryTransactionAttributeSourceAdvisor为匹配的Bean(有事物注解的Bean)创建事物代理。

2、事务属性 TransactionAttribute

Spring5.X 事务相关类介绍_第1张图片

定义与Spring兼容的事务属性的接口。 基于类似于EJB CMT属性的传播行为定义。定义了事物属性:事物传播机制、事物隔离级别、事务超时、是否只读、事务名称等属性承载体。

3、解析事务注解得到事物属性 TransactionAnnotationParser

Spring5.X 事务相关类介绍_第2张图片

用于解析已知事务注解类型的策略接口。 {@link AnnotationTransactionAttributeSource}委托给此类解析器,以支持特定的注解类型,例如Spring自己的 {@link Transactional},JTA 1.2的{@link javax.transaction.Transactional} 或EJB3的{@link javax.ejb.TransactionAttribute}。基于注解的事物注解解析器,用于解析方法、类或者父类及父类的方法上的事物注解。

3.1 SpringTransactionAnnotationParser

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// 查找@Transactional注解
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}

protected TransactionAttribute **parseTransactionAnnotation(AnnotationAttributes attributes)** {

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());
rbta.setReadOnly(attributes.getBoolean(“readOnly”));
rbta.setQualifier(attributes.getString(“value”));

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

3.2 JtaTransactionAnnotationParser

// 获取注解javax.transaction.Transactional
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
element, javax.transaction.Transactional.class);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}

protected TransactionAttribute **parseTransactionAnnotation(AnnotationAttributes attributes)** {

RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

rbta.setPropagationBehaviorName(
RuleBasedTransactionAttribute.PREFIX_PROPAGATION + attributes.getEnum(“value”).toString());

List rollbackRules = new ArrayList<>();
for (Class rbRule : attributes.getClassArray(“rollbackOn”)) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class rbRule : attributes.getClassArray(“dontRollbackOn”)) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);

return rbta;
}

3.3 Ejb3TransactionAnnotationParser

// 获取注解(javax.ejb.TransactionAttribute
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
javax.ejb.TransactionAttribute ann = element.getAnnotation(javax.ejb.TransactionAttribute.class);
if (ann != null) {
return parseTransactionAnnotation(ann);
}
else {
return null;
}
}

public TransactionAttribute** parseTransactionAnnotation(javax.ejb.TransactionAttribute ann)** {
return new Ejb3TransactionAttribute(ann.value());
}

private static class Ejb3TransactionAttribute extends DefaultTransactionAttribute {

public Ejb3TransactionAttribute(TransactionAttributeType type) {
setPropagationBehaviorName(PREFIX_PROPAGATION + type.name());
}

@Override
public boolean rollbackOn(Throwable ex) {
ApplicationException ann = ex.getClass().getAnnotation(ApplicationException.class);
return (ann != null ? ann.rollback() : super.rollbackOn(ex));
}
}

4、获取事务属性 TransactionAttributeSource

Spring5.X 事务相关类介绍_第3张图片

{@link TransactionAttributeSource}的抽象实现,该实现缓存方法的属性并实现回退策略:1.特定的目标方法; 2.目标阶层; 3.申报方法; 4.声明类/接口。 如果没有与目标方法关联的默认值,则使用目标类的事务属性。 与目标方法关联的任何事务属性都将完全覆盖类事务属性。 如果在目标类上未找到任何接口,则将检查已通过其调用方法的接口(在JDK代理的情况下)。 此实现在首次使用属性后按方法缓存属性。 如果曾经希望允许动态更改事务属性(这是不太可能的),则可以使缓存可配置。 缓存是可取的,因为需要评估回滚规则。

5、事务状态 TransactionStatus

事物状态的表示。事务代码可以使用它来检索状态信息,并以编程方式请求回滚(而不是引发引起隐式回滚的异常)。包括{@link SavepointManager} interface,以提供对保存点管理工具的访问。请注意,只有基础事务管理器支持时,保存点管理才可用。

Spring5.X 事务相关类介绍_第4张图片

6、事务信息 TransactionInfo

TransactionInfo封装了PlatformTransactionManager、TransactionAttribute、TransactionStatus、TransactionInfo(old)、joinpointIdentification(执行方法完全限定名称)。

7、事务管理器 PlatformTransactionManager

传送门《Spring5.X 事务管理器 PlatformTransactionManager》

你可能感兴趣的:(Spring5.x)