spring5.x-deklaratives Transaktionsprinzip und Quellcode-Implementierung

Oben: Spring5.x-AOP-Implementierungsprinzip und Quellcode-Analyse

Artikel dieser Reihe:
               

                    Spring5.x-AOP-Implementierungsprinzip und Quellcode-Analyse

                    Spring5.x-Listener-Prinzip und Quellcode-Implementierung

                    spring5.x-solve zirkuläre Abhängigkeitsanalyse

                    Lernen des Quellcodes des spring5.x-IOC-Moduls

                    Einführung in spring5.x und die dazugehörige Spring-Quellcode-Leseumgebung


Inhaltsverzeichnis

Oben: Spring5.x-AOP-Implementierungsprinzip und Quellcode-Analyse

Artikel dieser Reihe:               

                    Spring5.x-AOP-Implementierungsprinzip und Quellcode-Analyse

                    Spring5.x-Listener-Prinzip und Quellcode-Implementierung

                    spring5.x-solve zirkuläre Abhängigkeitsanalyse

                    Lernen des Quellcodes des spring5.x-IOC-Moduls

                    Einführung in spring5.x und die dazugehörige Spring-Quellcode-Leseumgebung

Grundwissen

Implementierungsprinzip der Frühlingstransaktion

Spring-Transaktionen funktionieren wie folgt:

Lernen des Frühlingstransaktionsquellcodes

@EnableTransactionManagement-Annotation

@EnableTransactionManagement->TransactionManagementConfigurationSelector

@EnableTransactionManagement->TransactionManagementConfigurationSelector->PROXY

@EnableTransactionManagement->TransactionManagementConfigurationSelector->ASPECTJ

Wie werden Anmerkungen verwendet?

@Transactional

Agentenimplementierung

zu guter Letzt


Grundwissen

Bitte lesen Sie zuerst den Originalartikel: Frühlingstransaktionsmanagement

Implementierungsprinzip der Frühlingstransaktion

Das Spring-Framework bietet Unterstützung für Transaktionen und ermöglicht Entwicklern die einfache Verwaltung von Transaktionsgrenzen, die Steuerung des Transaktionsausbreitungsverhaltens und der Transaktionsisolationsstufen in Anwendungen. Das Prinzip von Spring-Transaktionen basiert hauptsächlich auf zwei Schlüsselkonzepten: Transaktionsmanager und Aspekte.

  1. Transaktionsmanager: Der Transaktionsmanager ist für die Koordinierung und Verwaltung der Ausführung von Transaktionen verantwortlich. Es bietet Vorgänge wie das Starten einer Transaktion, das Festschreiben einer Transaktion und das Zurücksetzen einer Transaktion. Das Spring-Framework unterstützt eine Vielzahl von Transaktionsmanagern, beispielsweise den JDBC-Transaktionsmanager, den Hibernate-Transaktionsmanager und den JTA-Transaktionsmanager. Entwickler können je nach Bedarf den geeigneten Transaktionsmanager auswählen.

  2. Aspekt: ​​Im Spring-Framework wird das Transaktionsmanagement durch AOP (Aspektorientierte Programmierung) implementiert. Über AOP kann Spring vor und nach Methodenaufrufen Transaktionsverarbeitungslogik hinzufügen, um Transaktionen zu steuern. Entwickler können mithilfe der deklarativen Transaktionsverwaltung Transaktionsregeln konfigurieren und diese auf Zielmethoden anwenden.

Spring-Transaktionen funktionieren wie folgt:

  1. Transaktionsmanager konfigurieren: Zunächst müssen Entwickler einen geeigneten Transaktionsmanager in der Spring-Konfigurationsdatei konfigurieren. Sie können den vom Spring-Framework bereitgestellten Standard-Transaktionsmanager verwenden oder einen Transaktionsmanager anpassen.

  2. Transaktionsregeln definieren: Entwickler können das deklarative Transaktionsmanagement von Spring verwenden, um Transaktionsregeln zu definieren. Durch die Verwendung von Transaktionsaspekten und Pointcuts in der Konfigurationsdatei können Sie angeben, welche Methoden eine Transaktionsverwaltung erfordern, und Eigenschaften wie das Transaktionsweitergabeverhalten und die Isolationsstufe festlegen.

  3. Offene Transaktionsgrenzen: Wenn eine vom Transaktionsmanager verwaltete Methode aufgerufen wird, entscheidet Spring basierend auf Transaktionsregeln, ob eine Transaktion geöffnet werden soll. Wenn eine Transaktion gestartet werden muss, erstellt der Transaktionsmanager eine neue Transaktion und ordnet sie dem aktuellen Thread zu.

  4. Transaktions-Commit oder Rollback: Nachdem die Methodenausführung abgeschlossen ist, entscheidet der Transaktionsmanager basierend auf dem Ausführungsergebnis der Methode, ob die Transaktion festgeschrieben oder zurückgesetzt werden soll. Wenn die Methodenausführung erfolgreich ist, schreibt der Transaktionsmanager die Transaktion fest, um sie wirksam zu machen. Wenn die Methodenausführung fehlschlägt, setzt der Transaktionsmanager die Transaktion zurück, um sie ungültig zu machen.

  5. Verhalten bei der Transaktionsweitergabe: Wenn innerhalb einer Methode eine andere von einem Transaktionsmanager verwaltete Methode aufgerufen wird, bestimmt der Transaktionsmanager anhand der Verhaltensregeln für die Transaktionsweitergabe, ob er einer vorhandenen Transaktion beitritt oder eine neue Transaktion startet.

Zusammenfassung: Das Prinzip der Spring-Transaktionen basiert auf der Implementierung von Transaktionsmanagern und AOP. Der Transaktionsmanager ist für die Koordination und Verwaltung von Transaktionen verantwortlich, während AOP für das Hinzufügen von Transaktionsverarbeitungslogik vor und nach Methodenaufrufen verantwortlich ist. Durch die ordnungsgemäße Konfiguration der Transaktionsverwaltung und die Definition von Transaktionsregeln können Entwickler Transaktionen in Spring-Anwendungen problemlos verwalten.

Lernen des Frühlingstransaktionsquellcodes

@EnableTransactionManagement-Annotation

c3de05056c545b04abd667d7960501d6.png

Diese Annotation wird zum Starten einer Transaktion verwendet. Beachten Sie, dass bei Verwendung dieser Annotation eine PlatformTransactionManager-Bean registriert werden muss, andernfalls wird ein Fehler gemeldet.

@Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

@EnableTransactionManagement->TransactionManagementConfigurationSelector

Import über Import: TransactionManagementConfigurationSelector

Beachten Sie, dass der folgende Import einen Proxy (PROXY) und einen Aspekt (ASPECTJ) hat.

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    public TransactionManagementConfigurationSelector() {
    }

    protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
        //代理
        case PROXY:
        //这里有自动注册代理和
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
        //切面
        case ASPECTJ:
            return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
        default:
            return null;
        }
    }
}
@EnableTransactionManagement->TransactionManagementConfigurationSelector->PROXY

Codespeicherort: org.springframework.context.annotation.AutoProxyRegistrar

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.context.annotation;

import java.util.Iterator;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
//实现了ImportBeanDefinitionRegistrar接口。该类用于注册自动代理创建器。
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    private final Log logger = LogFactory.getLog(this.getClass());

    public AutoProxyRegistrar() {
    }
  //该方法根据传入的注解元数据和Bean定义注册表,查找具有特定属性的注解,并根据其属性值进行相应的操作。
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean candidateFound = false;
    //获取所有注解类型
        Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
    //获取迭代器
        Iterator var5 = annoTypes.iterator();
    //循环获取
        while(var5.hasNext()) {
      //获取下一个annotYPE
            String annoType = (String)var5.next();
      //获取属性
            AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
      //如果不为空才继续
            if (candidate != null) {
        //获取model属性
                Object mode = candidate.get("mode");
        //获取proxyTargetClass代理类的属性
                Object proxyTargetClass = candidate.get("proxyTargetClass");
        //两个都不为空 且类开为AdviceMode 且 proxyTargetClass
                if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
          //标记找到了修选的注解
                    candidateFound = true;
          //判断是AdviceMode类型注解
                    if (mode == AdviceMode.PROXY) {
            //通过aop方式注入到bean中(这里如果多次以第一次为主)
                        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
            //如果开启了cglib那么这里会进行代理开启(如果出现多次会进行覆盖)
                        if ((Boolean)proxyTargetClass) {
                            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                            return;
                        }
                    }
                }
            }
        }
    //若没有找到任务记录 进行提醒日志打印
        if (!candidateFound && this.logger.isWarnEnabled()) {
            String name = this.getClass().getSimpleName();
            this.logger.warn(String.format("%s was imported but no annotations were found having both 'mode' and 'proxyTargetClass' attributes of type AdviceMode and boolean respectively. This means that auto proxy creator registration and configuration may not have occurred as intended, and components may not be proxied as expected. Check to ensure that %s has been @Import'ed on the same class where these annotations are declared; otherwise remove the import of %s altogether.", name, name, name));
        }

    }
}

Abgeleitet vom obigen Code: AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);

Beachten Sie Folgendes: Wenn bei der Injektion durch Spring mehrere Bean-Namen mit demselben Namen vorhanden sind, wird nur einer beibehalten.

Codespeicherort: org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired

@Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
      //如果包含了,那么会直接覆盖(aop的优先级更大)
      //所以如果你的事务注解@EnableTransactionManagement和@EnableAspectJAutoProxy不管你哪个配在上面,都会被@EnableAspectJAutoProxy覆盖掉。切记切记
            BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }

            return null;
        } else {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", -2147483648);
            beanDefinition.setRole(2);
            registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
            return beanDefinition;
        }
    }

Codespeicherort: org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration

Die folgende Klasse ist eine Konfigurationsklasse

//被注解为@Configuration。该类用于配置代理模式下的事务管理。
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
  //该Bean对象是BeanFactoryTransactionAttributeSourceAdvisor类型,用于提供事务增强器(TransactionAttributeSource和TransactionInterceptor)。
  @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
    BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    advisor.setTransactionAttributeSource(transactionAttributeSource());
    advisor.setAdvice(transactionInterceptor());
    advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    return advisor;
  }
  //注册到Spring容器中。该Bean对象是AnnotationTransactionAttributeSource类型,用于从注解中获取事务属性。
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionAttributeSource transactionAttributeSource() {
    return new AnnotationTransactionAttributeSource();
  }
  //注册到Spring容器中。该Bean对象是TransactionInterceptor类型,用于实现具体的事务拦截逻辑。
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionInterceptor transactionInterceptor() {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource());
    if (this.txManager != null) {
      interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
  }

}

Beispiel: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration

//为一个抽象类,被注解为@Configuration。该类用于提供抽象的事务管理配置,并实现了ImportAware接口。
@Configuration
public abstract class AbstractTransactionManagementConfiguration implements ImportAware {
  //enableTx是一个AnnotationAttributes类型的变量,表示通过@EnableTransactionManagement注解获取的启用事务管理的属性。
  protected AnnotationAttributes enableTx;

  //txManager是一个PlatformTransactionManager类型的变量,表示默认的事务管理器,可以通过TransactionManagementConfigurer进行配置。
  protected PlatformTransactionManager txManager;

//根据传入的注解元数据(importMetadata),通过AnnotationMetadata的getAnnotationAttributes方法获取EnableTransactionManagement注解的属性值,并将其转换为AnnotationAttributes对象赋值给enableTx变量。如果enableTx为空,则抛出IllegalArgumentException异常。
  @Override
  public void setImportMetadata(AnnotationMetadata importMetadata) {
    this.enableTx = AnnotationAttributes.fromMap(
        importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
    if (this.enableTx == null) {
      throw new IllegalArgumentException(
          "@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
    }
  }
//通过该方法将configurers集合中的唯一一个TransactionManagementConfigurer对象的annotationDrivenTransactionManager方法返回的事务管理器赋值给txManager变量。(默认的事务管理器通过这个可以实现)
  @Autowired(required = false)
  void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
    if (CollectionUtils.isEmpty(configurers)) {
      return;
    }
    //仅允许配置一个
    if (configurers.size() > 1) {
      throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");
    }
    TransactionManagementConfigurer configurer = configurers.iterator().next();
    this.txManager = configurer.annotationDrivenTransactionManager();
  }

  //注册到Spring容器中。该Bean对象是TransactionalEventListenerFactory类型,用于处理事务相关的事件监听。
  @Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionalEventListenerFactory transactionalEventListenerFactory() {
    return new TransactionalEventListenerFactory();
  }

}

Codespeicherort: org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor

Zurück dazu in der Unterklasse gerade: BeanFactoryTransactionAttributeSourceAdvisor

//继承自AbstractBeanFactoryPointcutAdvisor注意:这里的advisor跟我之前aop是不是很像,其实就是那个advisor。该类用于根据事务属性源(TransactionAttributeSource)创建切点(Pointcut)
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
  //是一个TransactionAttributeSource类型的变量,用于存储事务属性源。
  private TransactionAttributeSource transactionAttributeSource;
  //是一个TransactionAttributeSourcePointcut类型的成员变量,通过匿名内部类的方式创建,并重写了getTransactionAttributeSource方法,该方法返回transactionAttributeSource对象。
  private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
    @Override
    protected TransactionAttributeSource getTransactionAttributeSource() {
      return transactionAttributeSource;
    }
  };


  //用于设置transactionAttributeSource变量的值。(可以通过这个手动设置事务属性源)
  public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
    this.transactionAttributeSource = transactionAttributeSource;
  }

  //用于设置pointcut的类过滤器(ClassFilter)。默认情况下,使用ClassFilter.TRUE。
  public void setClassFilter(ClassFilter classFilter) {
    this.pointcut.setClassFilter(classFilter);
  }

  @Override
  public Pointcut getPointcut() {
    return this.pointcut;
  }

}

Okay, achten wir als nächstes darauf: AbstractBeanFactoryPointcutAdvisor

Codespeicherort: org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor

//重点只看这段 用于设置通知(Advice)。这个就是我们原来aop的设置,可以看下原来的aop
public void setAdvice(Advice advice) {
        synchronized(this.adviceMonitor) {
            this.advice = advice;
        }
    }

BeanFactoryTransactionAttributeSourceAdvisor->TransactionAttributeSourcePointcut

Geben Sie Folgendes zurück: TransactionAttributeSourcePointcut

Codespeicherort: org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut

Diese Klasse ist die Implementierung von Aspekten, die auf Transaktionen angewendet werden. Fokus, Fokus, Fokus

//是一个抽象类,继承自StaticMethodMatcherPointcut类并实现了Serializable接口。
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
  //matches方法用于判断给定的方法和目标类是否匹配该切点。如果目标类不为null且是TransactionalProxy的子类或实现类,则返回false;否则,获取事务属性源(TransactionAttributeSource)并判断其是否为null,以及通过事务属性源获取给定方法和目标类的事务属性是否为null。如果事务属性为null,则返回false,否则返回true。(属于静态匹配)
  @Override
  public boolean matches(Method method, Class<?> targetClass) {
    if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
      return false;
    }
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (!(other instanceof TransactionAttributeSourcePointcut)) {
      return false;
    }
    TransactionAttributeSourcePointcut otherPc = (TransactionAttributeSourcePointcut) other;
    return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());
  }

  @Override
  public int hashCode() {
    return TransactionAttributeSourcePointcut.class.hashCode();
  }

  @Override
  public String toString() {
    return getClass().getName() + ": " + getTransactionAttributeSource();
  }


  //用于基于事务属性源来进行方法匹配和拦截。子类可以实现getTransactionAttributeSource方法来提供具体的事务属性源,从而根据事务的需求来进行方法的拦截和处理。
  protected abstract TransactionAttributeSource getTransactionAttributeSource();

}
@EnableTransactionManagement->TransactionManagementConfigurationSelector->ASPECTJ

Das Folgende ist relativ einfach. Es wird ein String-Array zurückgegeben, das TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME enthält. Wird bei der Konfiguration der Transaktionsverwaltung und Proxys verwendet. Unter Transaktionsmanagement versteht man die Verwaltung von Datenbanktransaktionen, während sich Proxy auf das Hinzufügen zusätzlicher Logikverarbeitung vor und nach Methodenaufrufen bezieht.

case ASPECTJ:
        return new String[] {
            TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};

public static final String TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
      "org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";

Wie werden Anmerkungen verwendet?

Wir alle wissen, dass wir die Annotation @Transactional verwenden, um Transaktionen im Spring-System zu starten.

Ich habe oben über den Berater gesprochen. Tatsächlich verwenden Frühlingstransaktionen auch die Idee von AOP, um die Logik von Aspekten zu implementieren. Es hat einfach seine eigene einzigartige Logik.

Codespeicherort: org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans

public List<Advisor> findAdvisorBeans() {
    //检查是否存在缓存的advisor bean名称数组cachedAdvisorBeanNames。如果cachedAdvisorBeanNames为空,那么调用BeanFactoryUtils工具类的beanNamesForTypeIncludingAncestors方法获取Advisor类型的bean名称,并将结果赋值给advisorNames,并将结果缓存到cachedAdvisorBeanNames中。
    String[] advisorNames = this.cachedAdvisorBeanNames; 
    if (advisorNames == null) {
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
  //值为空则直返回一个空数组
    if (advisorNames.length == 0) {
        return new ArrayList();
    } else {
        List<Advisor> advisors = new ArrayList();
        String[] var3 = advisorNames;
        int var4 = advisorNames.length;
      //通过循环判断每个name是否符合条件
        for(int var5 = 0; var5 < var4; ++var5) {
            String name = var3[var5];
            if (this.isEligibleBean(name)) {
                //如果当前bean正在创建中(isCurrentlyInCreation),则跳过该advisor,并记录调试日志。
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Skipping currently created advisor '" + name + "'");
                    }
                } else {
                    //加入到列表中
                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    } catch (BeanCreationException var10) {
                        Throwable rootCause = var10.getMostSpecificCause();
                        if (rootCause instanceof BeanCurrentlyInCreationException) {
                            BeanCreationException bce = (BeanCreationException)rootCause;
                            if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Skipping advisor '" + name + "' with dependency on currently created bean: " + var10.getMessage());
                                }
                                continue;
                            }
                        }

                        throw var10;
                    }
                }
            }
        }

        return advisors;
    }
}
@Transactional

Ermöglichen Sie Transaktionen über diese Anmerkung. Anschließend ermitteln wir in den vorherigen TransactionAttributeSourcePointcut.matches, ob die Annotation @Transactional enthalten ist. Wenn dies der Fall ist, bedeutet dies, dass Transaktionen aktiviert sind.

Die vorherige Initialisierungslogik ähnelt aop. Sie können aop überprüfen. Ich werde hier nicht auf Details eingehen.

Codespeicherort: org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>)

//用于判断给定的类是否适用于指定的切点(Pointcut)。
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        //如果为空直接抛出异常
        Assert.notNull(pc, "Pointcut must not be null");
        //不是这类过滤直接返回
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        } else {
            //如果 MethodMatcher 是 MethodMatcher.TRUE,表示匹配任何方法,则直接返回 true。
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            } else {
                //如果 MethodMatcher 是 IntroductionAwareMethodMatcher 的实例,将其赋值给 introductionAwareMethodMatcher。
                IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
                //判断是否这种类型
                if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
                }
              //用于保存目标class的对象
                Set<Class<?>> classes = new LinkedHashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                classes.add(targetClass);
                Iterator var6 = classes.iterator();
              //循环所有类对象
                while(var6.hasNext()) {
                    Class<?> clazz = (Class)var6.next();
                    //获取所有方法
                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                    Method[] var9 = methods;
                    int var10 = methods.length;
                  //通过matches来匹配方法(就是前面那个方法)
                    for(int var11 = 0; var11 < var10; ++var11) {
                        Method method = var9[var11];
                        if (introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
                            return true;
                        }
                    }
                }

                return false;
            }
        }
    }

Beachten Sie hier: TransactionAttributeSourcePointcut.matches

Diese Methode wurde kurz vor der Initialisierung implementiert. Dies wird verwendet, um festzustellen, ob es sich um eine Transaktion oder ein reines AOP handelt.

@Override
  public boolean matches(Method method, Class<?> targetClass) {
    if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
      return false;
    }
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
  }

Quelle: org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute

//重写了某个接口或者父类的getTransactionAttribute方法。
@Override
  public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
        //如果是object类型 直接返回
    if (method.getDeclaringClass() == Object.class) {
      return null;
    }

    // 生成一个缓存键(cacheKey),用于在属性缓存中查找或存储事务属性。
    Object cacheKey = getCacheKey(method, targetClass);
        //获取缓存中的值
    TransactionAttribute cached = this.attributeCache.get(cacheKey);
        //有值
    if (cached != null) {
      //判断是否为为空事务属性的对象,是直接返回null
      if (cached == NULL_TRANSACTION_ATTRIBUTE) {
        return null;
      }
      else {
                //不是返回该值
        return cached;
      }
    }
    else {
      // 如果缓存没有,那么查下事务注解中的属性
      TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
      // 解析出来为空 直放入缓存
      if (txAttr == null) {
        this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
      }
      else {
                //通过全类名+方法名生成方法标识
        String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
                //如果为DefaultTransactionAttribute 类型 则添加到属性中
        if (txAttr instanceof DefaultTransactionAttribute) {
          ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
        }
                //判断日志开关,有则打印日志
        if (logger.isDebugEnabled()) {
          logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
        }
                //最后加到缓存中
        this.attributeCache.put(cacheKey, txAttr);
      }
            //返回
      return txAttr;
    }
  }

Beachten Sie Folgendes: TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);

Die Implementierung ist wie folgt:

protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
    //判断是不是public 修饰的方法(这里也就是我们常说事务必须是public),发果不是直接返回null
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
    }

    // 获取目标类的用户类(userClass),忽略可能存在的 CGLIB 子类,仅对实际的用户类进行分析。
    Class<?> userClass = ClassUtils.getUserClass(targetClass);
    // The method may be on an interface, but we need attributes from the target class.
    // 获取最具体的方法(specificMethod),即在目标类及其父类/接口中查找最匹配的方法。
    Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
    //如果处理的方法包含泛型参数,则找到原始方法(BridgeMethodResolver.findBridgedMethod(specificMethod))。
    specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

    // 获取目前类是否有事务的属性,有则直接返回
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
      return txAttr;
    }

    // 如果目标类的方法中没有找到事务属性,则尝试从目标类本身获取事务属性(findTransactionAttribute(specificMethod.getDeclaringClass()))。
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
        //找到了事务属性,并且当前处理的是用户级别的方法(ClassUtils.isUserLevelMethod(method) 返回 true),则返回该事务属性
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
      return txAttr;
    }
      //如果是接口方法
    if (specificMethod != method) {
      // 去接口上方法找事务注解,如果不为空则直接返回
      txAttr = findTransactionAttribute(method);
      if (txAttr != null) {
        return txAttr;
      }
      // 去实现类找,如果不为空,有则返回
      txAttr = findTransactionAttribute(method.getDeclaringClass());
      if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        return txAttr;
      }
    }
      //最后啥都没就返回空
    return null;
  }

Die obige Logik lautet -> als öffentlich beurteilen -> zur Zieltransaktionsanmerkung gehen, um sie zu finden -> zur Schnittstelle gehen, um sie zu finden -> zur Schnittstellenimplementierungsklasse gehen, um sie zu finden

Agentenimplementierung

Dann müssen Sie verstehen, wie Transaktionen per Proxy implementiert werden. Tatsächlich ist der erste Abschnitt des Frühjahrsaufrufs derselbe wie bei AOP. Während des Anrufs müssen Sie lediglich feststellen, welche Art von Agent, AOP oder Cglib oder das eingeführte Framework verwendet wird.

Lassen Sie hier die Logik außer Acht, da der vorherige AOP-Typ direkt zu dieser Klasse geht: TransactionAspectSupport

Codespeicherort: org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

//代理调用模版
  protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
      throws Throwable {

    // If the transaction attribute is null, the method is non-transactional.
        //获取事务属性
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        //获取配置 的事务管理器对象
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
        //获取全路劲+方法名称+属性获取唯一标识符
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
      //如果属性为空 或 事务管理器对象不是为回滚类型
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      
            //创建事务
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      Object retVal = null;
      try {
        //通过钩子函数回调目标方法( 这个就是调用)
        retVal = invocation.proceedWithInvocation();
      }
      catch (Throwable ex) {
        // 回滚的实现
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
      }
      finally {
                //清空所有缓存
        cleanupTransactionInfo(txInfo);
      }
            //提交事务
      commitTransactionAfterReturning(txInfo);
      return retVal;
    }
      //编程事务 逻辑上面类似
            
    else {
      final ThrowableHolder throwableHolder = new ThrowableHolder();

      // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
      try {
        Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
            new TransactionCallback<Object>() {
              @Override
              public Object doInTransaction(TransactionStatus 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);
                }
              }
            });

        // Check result state: It might indicate a Throwable to rethrow.
        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;
      }
    }
  }

Tatsächlich besteht die obige Logik darin, eine Transaktion zu erstellen -> die Transaktion auszuführen -> die Transaktion zurückzusetzen/abzuschließen

Schauen Sie sich diese Methode im Inneren an: TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, jointpointIdentification);

protected TransactionInfo createTransactionIfNecessary(
      PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {

    // 不为空 则名称为空 
    if (txAttr != null && txAttr.getName() == null) {
            //通过连接点的ID定义成事务的名称
      txAttr = new DelegatingTransactionAttribute(txAttr) {
        @Override
        public String getName() {
          return joinpointIdentification;
        }
      };
    }

    TransactionStatus status = null;
    if (txAttr != null) {
      if (tm != null) {
                //获取事务状态
        status = tm.getTransaction(txAttr);
      }
      else {
        if (logger.isDebugEnabled()) {
          logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
              "] because no transaction manager has been configured");
        }
      }
    }
        //将事务的信息封装到 TransactionInfo 并返回
    return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  }

Im Code: status = tm.getTransaction(txAttr);

Codespeicherort: org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

@Override
  public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        //获取当前的事务对象。
    Object transaction = doGetTransaction();

    
    boolean debugEnabled = logger.isDebugEnabled();
      //判断方法传递为空
    if (definition == null) {
      //使用默认的进行实始化
      definition = new DefaultTransactionDefinition();
    }
      //该事务已存在
    if (isExistingTransaction(transaction)) {
      // Existing transaction found -> check propagation behavior to find out how to behave.
            //处理存在的事务并返回
      return handleExistingTransaction(definition, transaction, debugEnabled);
    }

    //检事事务设置的超时时间,如果超时则抛出悍异常
    if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
      throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
    }

    // 如果为事务为运行中的事务中,则抛出异常(代表没有事务)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
      throw new IllegalTransactionStateException(
          "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
            /*
            如果不存在已有的事务,则根据传入的事务定义的传播行为来决定如何处理新的事务。
如果传播行为为 PROPAGATION_MANDATORY,则抛出 IllegalTransactionStateException 异常,表示标记为 "mandatory" 的事务没有找到现有的事务。
如果传播行为为 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW 或 PROPAGATION_NESTED,则挂起当前事务资源,并创建一个新的事务,并返回一个新的 DefaultTransactionStatus 对象作为事务状态。在创建新事务之前,会检查是否需要同步事务,并准备相应的事务同步。如果在创建新事务过程中发生异常,则恢复挂起的事务资源,并重新抛出异常。
如果传播行为为其他值,则说明不需要实际的事务,但可能需要进行事务同步,所以会返回一个空的事务状态对象。
这里相当啰嗦~
            */
    else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
      SuspendedResourcesHolder suspendedResources = suspend(null);
      if (debugEnabled) {
        logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
      }
      try {
                //同步状态
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
                //构建事务的状态
        DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
                //创建一个新事务
        doBegin(transaction, definition);
                //绑定到线程变量去(这里相当复杂)
        prepareSynchronization(status, definition);
                //返回状态
        return status;
      }
      catch (RuntimeException ex) {
        resume(null, suspendedResources);
        throw ex;
      }
      catch (Error err) {
        resume(null, suspendedResources);
        throw err;
      }
    }
    else {
            //下面是创建一个空事务
      // Create "empty" transaction: no actual transaction, but potentially synchronization.
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
        logger.warn("Custom isolation level specified but no actual transaction initiated; " +
            "isolation level will effectively be ignored: " + definition);
      }
      boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
      return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
    }
  }

6b28ad6e22f1c752911cdfbf3dbb6da6.png

df0dbcd6fc632880cffe4113edc73c6c.png

Bezüglich des Kommunikationsverhaltens von Transaktionen lesen Sie es bitte selbst oder lesen Sie den Artikel: Spring Transaction Management

Nächster Code: doBegin(transaction, definition);

Es gibt drei Implementierungen. Der zweite wird hier verwendet.

000a7154a15a6663bf66c17c07fbf1e0.png

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

//
protected void doBegin(Object transaction, TransactionDefinition definition) {
    //转为事务对象 
    DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
    
        Connection con = null;

        try {
            //通过数据源获取数据库连接
            if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
                //获取边接
                Connection newCon = this.dataSource.getConnection();
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
                }
              //将数据库连接包装成一个ConnectionHolder,并放到 txObject属性中
                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
            }
          //标记当前连接为同步事务
            txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
            //获取连接
            con = txObject.getConnectionHolder().getConnection();
            //获取事务隔离级别,根据事务定义对连接进行必要的准备工作
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
            //设置进属性
            txObject.setPreviousIsolationLevel(previousIsolationLevel);
            //自动提交默认为true
            if (con.getAutoCommit()) {
                txObject.setMustRestoreAutoCommit(true);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
                }
              //开启事务
                con.setAutoCommit(false);
            }
          //判断事务是否只读
            this.prepareTransactionalConnection(con, definition);
            //设置事务为激活状态
            txObject.getConnectionHolder().setTransactionActive(true);
            //获取超时时间
            int timeout = this.determineTimeout(definition);
            //不为-1则进行设置超时时间属性
            if (timeout != -1) {
                txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
            }
          //如果为一个新事我国
            if (txObject.isNewConnectionHolder()) {
                //绑定key 和value 到线程池中
                TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder());
            }

        } catch (Throwable var7) {
            //如果在上述过程中发生异常,则会释放连接并抛出 CannotCreateTransactionException 异常,表示无法为事务打开数据库连接。
            if (txObject.isNewConnectionHolder()) {
                DataSourceUtils.releaseConnection(con, this.dataSource);
                txObject.setConnectionHolder((ConnectionHolder)null, false);
            }

            throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7);
        }
    }

Die obige Logik ist relativ leicht zu verstehen. Denn solange Sie mit dem Erlernen von JDBC fertig sind, können Sie es im Grunde verstehen.

Schließlich gibt es noch eine andere Art von Transaktion, nämlich eine verschachtelte Transaktion, also lernen wir auch diese kennen.

Gehen Sie zurück zu dieser Position: org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

if (isExistingTransaction(transaction)) {
      // Existing transaction found -> check propagation behavior to find out how to behave.
      return handleExistingTransaction(definition, transaction, debugEnabled);
    }
private TransactionStatus handleExistingTransaction(
      TransactionDefinition definition, Object transaction, boolean debugEnabled)
      throws TransactionException {
      //存在事务则跑出异常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
      throw new IllegalTransactionStateException(
          "Existing transaction found for transaction marked with propagation 'never'");
    }
      //存在外部事务则挂起事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
      if (debugEnabled) {
        logger.debug("Suspending current transaction");
      }
            //挂起事务
      Object suspendedResources = suspend(transaction);
      boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
            //创建一个新的非事务状态并返回
      return prepareTransactionStatus(
          definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }
      //存在外部事务,挂起外部事务,新建一个事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
      if (debugEnabled) {
        logger.debug("Suspending current transaction, creating new transaction with name [" +
            definition.getName() + "]");
      }
      SuspendedResourcesHolder suspendedResources = suspend(transaction);
      try {
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
        doBegin(transaction, definition);
        prepareSynchronization(status, definition);
        return status;
      }
      catch (RuntimeException beginEx) {
        resumeAfterBeginException(transaction, suspendedResources, beginEx);
        throw beginEx;
      }
      catch (Error beginErr) {
        resumeAfterBeginException(transaction, suspendedResources, beginErr);
        throw beginErr;
      }
    }
      //存在外部事务,融进外部事务中
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
      if (!isNestedTransactionAllowed()) {
        throw new NestedTransactionNotSupportedException(
            "Transaction manager does not allow nested transactions by default - " +
            "specify 'nestedTransactionAllowed' property with value 'true'");
      }
      if (debugEnabled) {
        logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
      }
            //支持保存在
      if (useSavepointForNestedTransaction()) {
      
                //开启一个新的事务并返回状态
        DefaultTransactionStatus status =
            prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
                //为事务创建一个回滚的点
        status.createAndHoldSavepoint();
        return status;
      }
      else {
        // Nested transaction through nested begin and commit/rollback calls.
        // Usually only for JTA: Spring synchronization might get activated here
        // in case of a pre-existing JTA transaction.
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, true, newSynchronization, debugEnabled, null);
        doBegin(transaction, definition);
        prepareSynchronization(status, definition);
        return status;
      }
    }

    // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
    if (debugEnabled) {
      logger.debug("Participating in existing transaction");
    }
        //是否验证事务
    if (isValidateExistingTransaction()) {
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
                //当前事务等级
        Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
                //为空或等级不一致 则抛出异常
        if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
                    
          Constants isoConstants = DefaultTransactionDefinition.constants;
          throw new IllegalTransactionStateException("Participating transaction with definition [" +
              definition + "] specifies isolation level which is incompatible with existing transaction: " +
              (currentIsolationLevel != null ?
                  isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
                  "(unknown)"));
        }
      }
            //不是为只读 且不一致 则抛出异常
      if (!definition.isReadOnly()) {
        if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
          throw new IllegalTransactionStateException("Participating transaction with definition [" +
              definition + "] is not marked as read-only but existing transaction is");
        }
      }
    }
    //最后 创建一个新的同步 并返回状态
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
  }

Diese Operationen werden schließlich von doComit() ausgeführt

8b19915fe25d782e085bbb67cb94b2ac.png

Rollback, wenn es fehlschlägt.

zu guter Letzt

Die Kernidee des Spring-Transaktionsmanagements besteht darin, die Transaktionssteuerung von der Geschäftslogik zu trennen, sodass der Geschäftscode nicht auf Details wie Transaktionseröffnung, -übermittlung oder -rollback achten muss. Durch die Verwendung des Transaktionsmanagers und der deklarativen Transaktionskonfiguration von Spring kann die Transaktionslogik vom Geschäftscode entkoppelt werden, wodurch eine flexiblere und einfachere Transaktionsverwaltungsmethode bereitgestellt wird. Relativ gesehen sind Spring-Transaktionen komplexer als AOP und erfordern eine Grundlage von AOP + JDBC. Dieser Artikel ist relativ einseitig und möglicherweise nicht leicht zu verstehen. Wenn Sie ihn wirklich nicht verstehen können, empfehle ich Ihnen, zum Vergleich den folgenden Artikel zu lesen.

Referenzartikel:

https://juejin.cn/post/6887751198737170446

https://blog.csdn.net/rongtaoup/article/details/127688984

https://www.cnblogs.com/dennyzhangdd/p/9602673.html

Supongo que te gusta

Origin blog.csdn.net/qq_16498553/article/details/132530610
Recomendado
Clasificación