fescar Q&A

一、前言

前面对fescar的源码做了一个分析,核心的流程基本已经有一个比较清晰的认知。这篇文章主要是对fescar的一些设计原理和目前看到一些问题做一个解答。鉴于本人没有跟开发者沟通过,有部分结论可能不一定准确。

二、Q&A

Q1.fescar解决了什么问题?

引用fescar的wiki上的说明:

Fescar 是 阿里巴巴 开源的 分布式事务中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题。

  1. 解决分布式事务问题
  2. 对业务0入侵
Q2.fescar如何实现?核心组件有哪些?

业界上分布式一致的解决方案主要有两种。

  1. 两段提交(2PC)
  2. paxos协议(包括raft协议等变体)
    fescar 使用的是2PC来实现。


    image
  • Transaction Coordinator(TC): 全局和分支事务的状态的保持,驱动这个全局的提交和回滚.
  • Transaction Manager(TM): 明确全局事务的范围:开始一个全局事务,提交或者回滚一个全局事务.
  • Resource Manager(RM): 管理分支事务工作资源,告诉TC,注册这个分支事务和上报分支事务的状态,驱动分支事务的的提交和回滚。
image
Q3.如何实现对业务0入侵

两段提交最核心的问题是如何实业务的自动回滚,feacar的解决方案是通过在RM上扩展原有的mysql连接代理,实现监听业务的sql。从而生成对应的回滚sql。
注意:由于需要在db更新前后增加一个select for update来获取变更前后的行值,因此业务要自行考虑这种方式对自己的业务是否允许。

Q4.xid如何生成?xid又是如何传输的?

TM向TC声明的一个事务开始的时候就会生成xid,所以xid是由TC生成的,TC如何保证xid的唯一?详细参考:
xid分析
事实上fescar的官方的xid方案是不能支持HA的,需要自己做扩展。

上面已经介绍了TM和TC的xid的生成过程。那么xid是如何在TM和RM,以及RM和RM之间传递的呢?
其实很简单,在dubbo基础上增加一个TransactionPropagationFilter来实现。

public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        String xid = RootContext.getXID();
        String rpcXid = RpcContext.getContext().getAttachment(RootContext.KEY_XID);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("xid in RootContext[" + xid + "] xid in RpcContext[" + rpcXid + "]");
        }
        boolean bind = false;
        if (xid != null) {
            RpcContext.getContext().setAttachment(RootContext.KEY_XID, xid);
        } else {
            if (rpcXid != null) {
                RootContext.bind(rpcXid);
                bind = true;
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("bind[" + rpcXid + "] to RootContext");
                }
            }
        }

RootContext获取xid成功,则会在请求协议的时候带上TX_XID这个属性。否则会读取请求体中的TX_XID写入RootContext。最终会让xid这个属性在请求的过程中一层层往下传递。

Q5.TC的global session和branch session如何存储?

源码详细分析:https://www.jianshu.com/p/051ff5640e1b
TC负责对整个事务的生命周期(状态)进行维护,因此global session和branch session是保存在TC上的。而fecar的官方例子session是保存在内存的,线上环境使用的时候需要自己扩展。

Q6.回滚操作如何保证数据的一致性

第一阶段提交到第二阶段提交中间数据被修改了怎么办?(ABA问题?)

这里的答案是用锁来解决。
fescar官方文档提到fescar在第一阶段提交的时候已经把锁释放掉了。其实feacar会在分支事务开始的时候会加锁,这个锁的状态是保存在TC。事实上官方说的释放锁只是把DB行锁释放,分支事务锁还是会持续保存。

public interface LockManager {

    boolean acquireLock(BranchSession branchSession) throws TransactionException;

    boolean isLockable(long transactionId, String resourceId, String lockKey) throws TransactionException;
}

这里存在3个问题。

  1. 这里缺少释放锁的操作,难道是做定时自动释放?难道不应该在第二段提交的时候把锁释放
  2. 官方提供的实现同样是基于内存的方案。需要做HA的自行进行改造
  3. 如果有一个分支事务的资源(db)有部分功能不接入fescar,会不会有问题?

对于问题3,我理解是fescar的使用场景的讨论,如果某个业务有一部分接入fescar,一部分不接入,则锁无法限制在第一次提交和回滚之间数据不会被修改的场景。因此我个人认为需要使用fescar必须将某个业务下的所有操作都要求统一接入到fescar,不管其中某个操作是否涉及到分布式事务。

Q8.TC的日志存储和查询

fescar使用自己定义的二进制格式进行日志保存,TransactionWriteStore,负责对事务session写入记录日志。目前只有保存到本地磁盘,线上使用需要一个统一的地方进行保存。而且查询日志的功能也需要自行开发。

Q9.TM如何决定何时需要回滚?

public Object execute(TransactionalExecutor business) throws TransactionalExecutor.ExecutionException {

        // 1. get or create a transaction
        GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();

        // 2. begin transaction
        try {
            tx.begin(business.timeout(), business.name());

        } catch (TransactionException txe) {
            throw new TransactionalExecutor.ExecutionException(tx, txe,
                TransactionalExecutor.Code.BeginFailure);

        }

        Object rs = null;
        try {

            // Do Your Business
            rs = business.execute();

        } catch (Throwable ex) {

            // 3. any business exception, rollback.
            try {
                tx.rollback();

                // 3.1 Successfully rolled back
                throw new TransactionalExecutor.ExecutionException(tx, TransactionalExecutor.Code.RollbackDone, ex);

            } catch (TransactionException txe) {
                // 3.2 Failed to rollback
                throw new TransactionalExecutor.ExecutionException(tx, txe,
                    TransactionalExecutor.Code.RollbackFailure, ex);

            }

        }

        // 4. everything is fine, commit.
        try {
            tx.commit();

        } catch (TransactionException txe) {
            // 4.1 Failed to commit
            throw new TransactionalExecutor.ExecutionException(tx, txe,
                TransactionalExecutor.Code.CommitFailure);

        }
        return rs;
    }

当TM执行业务逻辑抛出异常就会触发回滚操作。这意味着如果TM把分支事务的异常catch了,或者分支事务返回一个失败的返回码,但是TM没有对其进行正常的处理,就不能正常地触发回滚行为。
详见:https://www.jianshu.com/p/6547aa46452b

Q10.支持的数据库

目前仅支持mysql,当然你也可以加入到其中对其他数据库进行支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容