spring事务底层源码解析

1.@EnableTransactionManagement注解

 

可以看出,该注解作用就是向spring容器中添加两个Bean:(1)AutoProxyRegistrar;

AutoProxyRegistrar只有一个方法registerBeanDefinitions,该方法的目的就是注册一个InfrastructureAdvisorAutoProxyCreator,该类又继承了AbstractAdvisorAutoProxyCreator,所以这个类的作用就是开启动态代理,相当于一个BeanPostProcessor,在初始化后会去寻找Advisor类型的Bean,并判断当前某个Bean是否有匹配的Advisor,是否需要利用动态代理产生一个对象。相对应的源码如下:

 

 

(2)ProxyTransactionManagementConfiguration

已经知道,spring事务是通过AOP动态代理实现的,而ProxyTransactionManagementConfiguration的作用就是产生一个Advisor,Advisor中的TransactionAttributeSource相当于PointCut,用来判断@Transactional注解;TransactionInterceptor就是代理逻辑,当判断存在@Transactional注解,就会产生一个代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor中的invoke()方法。

下面开始展开对spring事务源码的分析,即TransactionInterceptor中的invoke()方法:

demo

 

@Transactional注解的默认传播机制是REQUIRED,即没有事务则创建一个新事务,有事务则在当前事务中执行。

1.调用invokeWithinTransaction创建事务

 

2.protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {
       // TransactionAttribute就是@Transactional中的配置
       TransactionAttributeSource tas = getTransactionAttributeSource();
       // 获取@Transactional中的属性值,该值必不为空,因为存在默认值
       final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
       // 返回Spring容器中类型为TransactionManager的Bean对象
       final TransactionManager tm = determineTransactionManager(txAttr);
       // 将TransactionManager强制转换成PlatFormTransactionManager
       PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
       // 获取当前在执行的方法的名字
       final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
       // 创建事务,获取被挂起的事务
       TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
       Object retVal;
       try {
           // 执行被代理对象中的方法
            retVal = invocation.proceedWithInvocation(); //test
       }catch (Throwable ex) {
           // 如果抛异常,则进行回滚
           completeTransactionAfterThrowing(txInfo, ex);
           throw ex;
       }finally {
           cleanupTransactionInfo(txInfo);
       }
       // 提交事务,具体看第7步
       commitTransactionAfterReturning(txInfo);
   }
3.protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
       TransactionStatus status = null;
       // 获取事务(重要方法),AbstractPlatFormTransactionManager
       status = tm.getTransaction(txAttr);
       // 返回一个TransactionInfo对象,表示得到了一个事务,可能是新创建的一个事务,也可能是拿到的已有的事务
       return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
   }
4.public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
      throws TransactionException {
          // 得到一个新的DataSourceTransactionObject对象,
          // 此时并没有创建数据库连接ConnectionHolder
          // new DataSourceTransactionObject  txObject
          // txObject中的ConnectionHolder置为false
          Object transaction = doGetTransaction();
          // 调通test方法时,该事务是不存在的,即没有开启过事务
          // 在第五步中的doBegin()方法里已经对transaction进行了更改,那么在调用a方法时,已经存在了事务
          if (isExistingTransaction(transaction)) {
              return handleExistingTransaction(def, transaction, debugEnabled);
          }
          // 当前Thread中没有事务时,这三个传播机制是等价的
          if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
              def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
              def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
          // 调用test时,一开始既然还没开启事务,这里是不会存在挂起对象的,这一步我觉得没什么意义
          // suspend方法中会去判断ThreadLocal<Set<TransactionSynchronization>> synchronizations
          // synchronizations是在下面的开启事务方法中的prepareSynchronization中的initSynchronization对ThreadLocal变量赋值
          SuspendedResourcesHolder suspendedResources = suspend(null);
          // 开启事务,创建数据库连接
          return startTransaction(def, transaction, debugEnabled, suspendedResources);
      }
      }

 

5./**
 * Start a new transaction.
 */
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
      boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
          
          DefaultTransactionStatus status = newTransactionStatus(
             definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
          // 开启事务
          // 1.创建数据库连接con;2.将txObject.ConnectionHolder置为true,并且与数据源dataSource绑定
          // 3.将txObject的ConnectionHolder中的TransactionActive属性置为true
         doBegin(transaction, definition);
         prepareSynchronization(status, definition);
         return status;
      }
6.private TransactionStatus handleExistingTransaction(
      TransactionDefinition definition, Object transaction, boolean debugEnabled)
      throws TransactionException {
          // 根据不同的传播级别,判断是否需要创建新的事务
          
          // 1.Propagation.NOT_SUPPORTED:挂起当前事务,但是不开启新的连接
          if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
              if (debugEnabled) {
                  logger.debug("Suspending current transaction");
             }
             // 把当前事务挂起,其中就会把数据库连接对象从ThreadLocal中移除
             Object suspendedResources = suspend(transaction);
             boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
             return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
         }
         // 2.Propagation.REQUIRES_NEW:挂起当前事务并开启新的连接
          if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
              SuspendedResourcesHolder suspendedResources = suspend(transaction);
              return startTransaction(definition, transaction, debugEnabled, suspendedResources);
          }
          
      }
7.public final void commit(TransactionStatus status) throws TransactionException {
    
    if (defStatus.isLocalRollbackOnly()) {
       if (defStatus.isDebug()) {
          logger.debug("Transactional code has requested rollback");
       }
       processRollback(defStatus, false);
       return;
   }
   // 判断此事务在之前是否设置了需要回滚,跟globalRollbackOnParticipationFailure有关
  if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
      processRollback(defStatus, true);
      return;
  }
  // 提交事务,最后会恢复被挂起的资源
  processCommit(defStatus);
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值