结合seata和2PC,简单聊聊seata源码

当前代码分析基于seata1.6.1

整体描述

整体代码流程可以描述为

  1. TM开启全局事务,会调用TC来获取XID。
  2. TC在接收到通知后,会生成XID,然后会将当前全局事务保存到global_table表中,并且返回XID。
  3. 在获取到XID后,会执行业务逻辑。
  4. 执行业务逻辑的时候,如果发生了增删改,则会对增删改语句做增强。
  5. 获取前置镜像数据---执行sql,不提交事务--获取后置镜像---准备undoLog---作为RM向TC提交事务分支---生成undo_log日志---提交本地事务,注意,在这里,本地事务已经提交了。只是有undo_log可用于回滚。
  6. TC接收RM端提交的分支事务,存储到brand_table中。
  7. 当全局分支事务都执行完成,TM会向TC提起全局事务提交的请求。
  8. TC接收到请求后,删除全局事务和分支事务(global_table 和 brand_table)。
  9. TC 通知RM,删除 undo log 日志。

源码解析

系统启动初始化

主要完成两个事情:初始化 TM和RM客户端;创建方法拦截器

在客户端中,核心配置类是SeataAutoConfiguration,在这个类中初始化了一个核心的扫描器GlobalTransactionScanner。

GlobalTransactionScanner 全局事务扫描器,实现了InitializingBean接口,如果继承了该接口,spring会在完成DI之后,调用afterPropertiesSet方法,在该方法中完成了对TM客户端和RM客户端的创建,代码如下

@Override
public void afterPropertiesSet() {
    if (disableGlobalTransaction) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Global transaction is disabled.");
        }
        ConfigurationCache.addConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
                (ConfigurationChangeListener)this);
        return;
    }
    if (initialized.compareAndSet(false, true)) {
        //创建客户端的方法
        initClient();
    }
}


private void initClient() {
    ...其他校验
    //创建TM客户端并且初始化
    TMClient.init(applicationId, txServiceGroup, accessKey, secretKey);
    ...
    //创建RM客户端并且初始化
    RMClient.init(applicationId, txServiceGroup);
    ...

}

同时,GlobalTransactionScanner 继承了AbstractAutoProxyCreator 抽象类,在类完成初始化之后,会调用父类的 postProcessAfterInitialization方法,在父类的方法中,会调用该类重写的一个wrapIfNecessary方法。

wrapIfNecessary 方法会生成一个 GlobalTransactionalInterceptor 全局事务拦截器。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // do checkers
        if (!doCheckers(bean, beanName)) {
            return bean;
        }

        try {
            synchronized (PROXYED_SET) {
                if (PROXYED_SET.contains(beanName)) {
                    return bean;
                }
                interceptor = null;
                //check TCC proxy
                if (TCCBeanParserUtils.isTccAutoProxy(bean, beanName, applicationContext)) {
                    ...
                } else {
                    ...
                    //生成一个全局事务处理的拦截器,
                    if (globalTransactionalInterceptor == nul
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值