前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >seata tcc模式下的一个性能问题

seata tcc模式下的一个性能问题

作者头像
IT云清
发布2020-01-13 16:29:22
1.7K0
发布2020-01-13 16:29:22
举报
文章被收录于专栏:IT云清
本文解释Seata中,AT模式和MT模式下的一个一阶段的区别。

根据两阶段行为模式的不同,Seata将分支事务划分为2种:

  • Automatic (Branch) Transaction Mode
  • Manual (Branch) Transaction Mode

1.AT模式

AT 模式基于 支持本地 ACID 事务 的 关系型数据库:

一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。

2. MT模式

相应的,MT 模式,不依赖于底层数据资源的事务支持: 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。 二阶段 commit 行为:调用 自定义 的 commit 逻辑。 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。 所谓 MT 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

3.一阶段解读

在AT模式下,一阶段会做如下几个操作:

1.解析业务sql; 2.获取sql执行前的镜像,前镜像; 3.执行业务sql; 4.获取sql执行后的镜像,后镜像; 5.添加undo_log日志,把前后镜像数据和业务sql相关的信息组成回滚日志,添加到undo_log中; 6.向TC注册分支事务,并申请相关目标数据的全局锁; 7.事务提交,将业务操作和undo_log一起提交; 8.上报分支事务提交结果给TC; 9.释放本地锁; 10.释放数据库连接;

在AT模式下,一阶段,会有如上的多个步骤,以及解析存储undo_log等操作;那么,在MT模式中,由于prepare逻辑有对应的rollback逻辑,显然这里是不用再添加回滚信息的。那么,这MT模式下一阶段的处理逻辑,是如何避免上述操作带来的性能损耗呢?

4.源码分析

在方法拦截器MethodInterceptor接口下,有一个TCC拦截器实现类TccActionInterceptor,这个实现类有一个invoke方法:

代码语言:javascript
复制
   @Override
    public Object invoke(final MethodInvocation invocation) throws Throwable {
        if(!RootContext.inGlobalTransaction()){
            //not in transaction
            return invocation.proceed();
        }
        Method method = getActionInterfaceMethod(invocation);
        TwoPhaseBusinessAction businessAction = method.getAnnotation(TwoPhaseBusinessAction.class);
        //try method
        if (businessAction != null) {
            //save the xid
            String xid = RootContext.getXID();
            //clear the context
            RootContext.unbind();
            try {
                Object[] methodArgs = invocation.getArguments();
                //Handler the TCC Aspect
                Map<String, Object> ret = actionInterceptorHandler.proceed(method, methodArgs, xid, businessAction,
                        new Callback<Object>() {
                            @Override
                            public Object execute() throws Throwable {
                                return invocation.proceed();
                            }
                        });
                //return the final result
                return ret.get(Constants.TCC_METHOD_RESULT);
            } finally {
                //recovery the context
                RootContext.bind(xid);
            }
        }
        return invocation.proceed();
    }

可以看到,在切面的切入点执行之前,和之后,有2个关键操作: 把xid解绑

代码语言:javascript
复制
//save the xid
String xid = RootContext.getXID();
//clear the context
RootContext.unbind();

恢复xid绑定

代码语言:javascript
复制
//recovery the context
RootContext.bind(xid);

这么做的目的是什么呢?

当把xid解绑后,tcc的这个prepare分支事务执行时,框架不会拦截业务sql进行解析,也不会存储前后镜像和生成undo_log日志,(即使使用了代理数据源,也不会)这样,tcc模式下,就避免了一阶段的上述操作带来的损耗。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/09/03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本文解释Seata中,AT模式和MT模式下的一个一阶段的区别。
  • 1.AT模式
  • 2. MT模式
  • 3.一阶段解读
  • 4.源码分析
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档