欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring5.X 事务相关类介绍

程序员文章站 2022-07-12 11:23:12
...

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 事务相关类介绍

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

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

Spring5.X 事务相关类介绍

用于解析已知事务注解类型的策略接口。 {@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 事务相关类介绍

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

5、事物状态 TransactionStatus

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

Spring5.X 事务相关类介绍

6、事物信息 TransactionInfo

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

7、事务管理器 PlatformTransactionManager

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

相关标签: Spring5.x