AT模式遇到的问题与具体源码篇

本文深入探讨了Seata AT模式下,从TM如何开启全局事务,到TM如何提交/回滚,再到RM的回滚日志生成、全局锁获取以及TC如何协调分支事务的细节。通过分析关键类如TransactionalTemplate和ExecuteTemplate的源码,揭示了Seata在处理分布式事务中的具体实现策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于AT模式的流程,我们在上一篇文章 一文简要概述Seata AT与TCC的区别
已经介绍的差不多了。但是日常学习中,我们仅仅只知道一个流程是远远不够的。我们往往会遇到许多问题,现在根据几个我在学习Seata时产生的几个问题,进入源码中了解下具体是怎么实现的。

开始之前,介绍几个AT模式下比较重要的类

TM 操作核心代码 io.seata.tm.api.TransactionalTemplate
RM 操作核心代码 io.seata.rm.datasource.exec.ExecuteTemplate

2.1 TM是如何开启全局事务的
// io.seata.tm.api.TransactionalTemplate#beginTransaction
private void beginTransaction(TransactionInfo txInfo, GlobalTransaction tx) throws TransactionalExecutor.ExecutionException {
   
  try {
   
    // 钩子方法
    triggerBeforeBegin();
    // 开去全局事务
    tx.begin(txInfo.getTimeOut(), txInfo.getName());
    // 钩子方法
    triggerAfterBegin();
  } catch (TransactionException txe) {
   
    throw new TransactionalExecutor.ExecutionException(tx, txe,
                                                       TransactionalExecutor.Code.BeginFailure);

  }
}
// io.seata.tm.api.DefaultGlobalTransaction#begin(int, java.lang.String)
@Override
public void begin(int timeout, String name) throws TransactionException {
   
  if (role != GlobalTransactionRole.Launcher) {
   
    assertXIDNotNull();
    if (LOGGER.isDebugEnabled()) {
   
      LOGGER.debug("Ignore Begin(): just involved in global transaction [{}]", xid);
    }
    return;
  }
  assertXIDNull();
  String currentXid = RootContext.getXID();
  if (currentXid != null) {
   
    throw new IllegalStateException("Global transaction already exists," +
                                    " can't begin a new global transaction, currentXid = " + currentXid);
  }
  // 通过RPC请求调用到TC服务
  xid = transactionManager.begin(null, null, name, timeout);
  status = GlobalStatus.Begin;
  RootContext.bind(xid);
  if (LOGGER.isInfoEnabled()) {
   
    LOGGER.info("Begin new global transaction [{}]", xid);
  }
}
// io.seata.server.coordinator.DefaultCore#begin
@Override
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
  throws TransactionException {
   
  // 创建全局事务
  GlobalSession session = GlobalSession.createGlobalSession(applicationId, transactionServiceGroup, name,
                                                            timeout);
  session.addSessionLifecycleListener(SessionHolder.getRootSessionManager());

  session.begin()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值