ByteTCC 源码分析 - 事务流程 - 开启事务

130 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天

TransactionInfo

获取Transaction,获取TransactionStatus,开启事务。

UserTrasactionManager:
TransactionManager:
XAResource:

@Transactional注解通过AOP执行TransactionInterceptor,拦截请求,执行事务流程:

  1. begin:启动一个事务(TransactionManager)
  2. 执行目标方法内部的业务逻辑
  3. 根据目标方法执行是否成功或者是报错,选择commit/rollback(TransactionManager)

CompensableHandlerInterceptor & HandlerInterceptor

MVC拦截器

CompensableMethodInterceptor & MethodInterceptor

AOP拦截器

获取目标Controller方法的@Transactional注解及@Compensable注解。 判断是否是simplified模式,如果simplified = true,在当前类中,就会有@CompensableConfirm和@CompensableCancel注解标记的TCC事务需要的confirm和cancel方法。

CompensableInvocation

封装本次调用的一些信息。目标的Controller、目标的方法、目标的@Compensable注解。

  1. transaction 不为空,开启普通事务
  2. invocation 不为空,开启补偿性事务
  3. 开启单机事务

// TransactionManagerImpl.java & javax.transaction.TransactionManager

if (transaction != null) {
   compensableManager.begin();
} else if (invocation != null) {
   compensableManager.compensableBegin();
} else {
   // 支持单机事务
   transactionManager.begin();
}

CompensableManagerImpl

  1. 创建全局事务上下文
  2. 创建分支事务上下文
  3. 创建补偿型事务,并绑定到当前线程
  4. 开启事务


// CompensableManagerImpl & javax.transaction.TransactionManager

public void compensableBegin() throws NotSupportedException, SystemException {

   //
   // ... 删掉无用代码 ...
   //

   // xid
   TransactionXid compensableXid = compensableXidFactory.createGlobalXid();
   TransactionXid transactionXid = transactionXidFactory.createGlobalXid(compensableXid.getGlobalTransactionId());

   // TransactionContext
   TransactionContext compensableContext = new TransactionContext();
   compensableContext.setCoordinator(true);
   compensableContext.setCompensable(true);
   compensableContext.setXid(compensableXid);
   compensableContext.setPropagatedBy(compensableCoordinator.getIdentifier());
   
   // CompensableTransactionImpl
   CompensableTransactionImpl compensable = new CompensableTransactionImpl(compensableContext);
   compensable.setBeanFactory(this.beanFactory);

   this.associateThread(compensable);

   // TransactionContext
   TransactionContext transactionContext = new TransactionContext();
   transactionContext.setXid(transactionXid);

   boolean failure = true;
   try {
      this.invokeBegin(transactionContext, true);
      failure = false;
   } finally {
      if (failure) {
         this.desociateThread();
      }
   }

   compensableRepository.putTransaction(compensableXid, compensable);

   //
   // ... 删掉无用代码 ...
   //

   // 写死的 return true...
   boolean locked = compensableLock.lockTransaction(compensableXid, this.endpoint);
   if (locked == false) {
      this.invokeRollbackInBegin(transactionContext);

      compensableLogger.deleteTransaction(compensable.getTransactionArchive());
      this.desociateThread();
      compensableRepository.removeTransaction(compensableXid);

      throw new SystemException(); // should never happen
   }

   //
   // ... 删掉无用代码 ...
   //
   
   // 3e90011619ed00000182b58cae7f00075b98e250| compensable transaction begin!
    logger.info("{}| compensable transaction begin!", ByteUtils.byteArrayToString(compensableXid.getGlobalTransactionId()));
}

TransactionContext

分布式事务上下文

CompensableTransactionImpl

代表一个分布式事务的对象(补偿型事务)

compensableLock.lockTransaction

写死的?真霸道。

public boolean lockTransaction(TransactionXid transactionXid, String identifier) {
   return true;
}

TransactionStatus

代表当前方法上的事务的状态。由PlatformTransactionManager.getTransaction(TransactionAttribute)获取。

prepareTransactionInfo

预处理TransactionInfo,构造成事务链。内部有一个oldTransactionInfo代表调用方法的事务,TransactionInfo.this代表当前方法的事务,即被调用方法。