spring源码系列11:事务代理对象的执行(上)

简介: spring源码系列11:事务代理对象的执行(上)

回顾


spring源码系列9:事务代理的创建一节, 事务通过定义

  • 切点: TransactionAttributeSourcePointcut 、
  • 通知(拦截器) TransactionInterceptor
  • Advisor:  BeanFactoryTransactionAttributeSourceAdvisor
    在AOP基础上实现事务代理的功能

spring源码系列10:AOP代理对象的执行一节。 总结出,不管是AOP-JDK代理还是CGLB动态代理,都会执行Advice完成增强功能。

也就是说:事务的核心功能就在这个TransactionInterceptor


事务执行


TransactionInterceptor

@Override
  public Object invoke(final MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
      @Override
      public Object proceedWithInvocation() throws Throwable {
        return invocation.proceed();
      }
    });
  }

交给父类TransactionAspectSupport.invokeWithinTransaction()去执行


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.
    1.
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    2.
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    3.
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      // Standard transaction demarcation with getTransaction and commit/rollback calls.
      4.
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      Object retVal = null;
      try {
        // This is an around advice: Invoke the next interceptor in the chain.
        // This will normally result in a target object being invoked.
        5.
        retVal = invocation.proceedWithInvocation();
      }
      catch (Throwable ex) {
        // target invocation exception
        6.
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
      }
      finally {
      7.
        cleanupTransactionInfo(txInfo);
      }
      8.
      commitTransactionAfterReturning(txInfo);
      return retVal;
    }
    ... 
  }


1.拿到事务属性TransactionAttribute :

我们使用注解@Transactional时,注解元信息会被包装成TransactionAttribute ,此处拿到的就是@Transactional的元数据


2.determineTransactionManager(txAttr)

找到一个合适的事务管理器

protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
    // Do not attempt to lookup tx manager if no tx attributes are set
    //未设置事务属性,也没有设置beanFactory ,直接返回
    if (txAttr == null || this.beanFactory == null) {
      return getTransactionManager();
    }
    //如果@Transactional 指定了具体事务管理器,则根据beanname去容器中找到他
    String qualifier = txAttr.getQualifier();
    if (StringUtils.hasText(qualifier)) {
      return determineQualifiedTransactionManager(qualifier);
    }
    //如果是TransactionAspectSupport.transactionManagerBeanName指定了具体事务管理器,
    //beanname去容器中找
    else if (StringUtils.hasText(this.transactionManagerBeanName)) {
      return determineQualifiedTransactionManager(this.transactionManagerBeanName);
    }
    //没有beanName指定具体的事务管理器Bean。
    /**
    1.查看transactionManager属性是否设置事务管理器对象
    2.查看事务管理器缓存中有没有
    3.去容器中寻找,找PlatformTransactionManager接口的实现类。getBean(PlatformTransactionManager),
    找到放到事务管理器缓存中。
    **/
    else {
      PlatformTransactionManager defaultTransactionManager = getTransactionManager();
      if (defaultTransactionManager == null) {
        defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
        if (defaultTransactionManager == null) {
          defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
          this.transactionManagerCache.putIfAbsent(
              DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
        }
      }
      return defaultTransactionManager;
    }
  }

以集成了DataSourceTransactionManager为例。determineTransactionManager返回的就是DataSourceTransactionManager对象。


3.methodIdentification方法

获取目标方法全名


4.createTransactionIfNecessary开启事务重点

protected TransactionInfo createTransactionIfNecessary(
      PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
    // If no name specified, apply method identification as transaction name.
    如果事务名称没有指定,则使用方法名作为事务名
    if (txAttr != null && txAttr.getName() == null) {
      txAttr = new DelegatingTransactionAttribute(txAttr) {
        @Override
        public String getName() {return joinpointIdentification;}
      };
    }
    ...
    TransactionStatus status = tm.getTransaction(txAttr);
    ...
    return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
  }


重点在

  • getTransaction方法获取TransactionStatus 事务
  • prepareTransactionInfo方法上,封装一个TransactionInfo
4.1:getTransaction ()

getTransaction ()是一个模板方法,PlatformTransactionManager定义了getTransaction 方法。抽象类AbstractPlatformTransactionManager实现了getTransaction 方法。因为是模板方法。方法内很多方法都是在具体的PlatformTransactionManager实现的。(本文以DataSourceTransactionManager为例)


public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
    1.尝试获取事务对象,并封装当前线程中以当前datasource为key的Connection。
    Object transaction = doGetTransaction();
    2.没有配置事务属性,则创建一个默认的事务属性
    if (definition == null) {
      // Use defaults if no transaction definition given.
      definition = new DefaultTransactionDefinition();
    }
    3.判断是否有已经存在是否:判断条件是当前线程有Connection.并且Connection是活跃的
    if (isExistingTransaction(transaction)) {
      // Existing transaction found -> check propagation behavior to find out how to behave.
      已存在事务,则处理传播属性,然后返回。(处理两个事务之间的传播属性关系)
      return handleExistingTransaction(definition, transaction, debugEnabled);
    }
    ===========当前没有事务
    // Check definition settings for new transaction.
    4.超时时间校验
    if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
      throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
    }
    5.开始处理当前事务
    // No existing transaction found -> check propagation behavior to find out how to proceed.
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
      throw new IllegalTransactionStateException(
          "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
    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);
    }
  }

下面拆解此方法


相关文章
|
2天前
|
SQL Java 关系型数据库
Spring 事务
Spring 事务
6 1
|
2天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
12 1
|
3天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
44 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
4天前
|
Java 数据库连接 数据库
Spring事务简介,事务角色,事务属性
Spring事务简介,事务角色,事务属性
15 2
|
8天前
|
Java 数据库连接 数据库
16:事务-Java Spring
16:事务-Java Spring
25 5
|
8天前
|
SQL Java 数据库连接
15:MyBatis对象关系与映射结构-Java Spring
15:MyBatis对象关系与映射结构-Java Spring
29 4
|
10天前
|
消息中间件 Java 关系型数据库
Spring事务与分布式事务
这篇文档介绍了事务的概念和数据库事务的ACID特性:原子性、一致性、隔离性和持久性。在并发环境下,事务可能出现更新丢失、脏读和不可重复读等问题,这些问题通过设置事务隔离级别(如读未提交、读已提交、可重复读和序列化)来解决。Spring事务传播行为有七种模式,影响嵌套事务的执行方式。`@Transactional`注解用于管理事务,其属性包括传播行为、隔离级别、超时和只读等。最后提到了分布式事务,分为跨库和跨服务两种情况,跨服务的分布式事务通常通过最终一致性策略,如消息队列实现。
|
11天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
11天前
|
监控 Java 测试技术
Spring Boot与事务钩子函数:概念与实战
【4月更文挑战第29天】在复杂的业务逻辑中,事务管理是确保数据一致性和完整性的关键。Spring Boot提供了强大的事务管理机制,其中事务钩子函数(Transaction Hooks)允许开发者在事务的不同阶段插入自定义逻辑。本篇博客将详细探讨事务钩子函数的概念及其在Spring Boot中的应用。
31 1
|
12天前
|
JSON Java 数据处理
Spring Boot与Jsonson对象:灵活的JSON操作实战
【4月更文挑战第28天】在现代Web应用开发中,JSON数据格式的处理至关重要。假设 "Jsonson" 代表一个类似于Jackson的库,这样的工具在Spring Boot中用于处理JSON。本篇博客将介绍Spring Boot中处理JSON数据的基本概念,并通过实际例子展示如何使用类似Jackson的工具进行数据处理。
22 0