分布式架构

fescar源码分析2

2019-02-02  本文已影响23人  leiwingqueen

一、概要

今天开始重点分析TC和RM的通讯方式。涉及到的核心类

二、TC核心实现

DefaultCoordinator,事务协调器,简称TC,核心实现在DefaultCore这个类里面。
DefaultCore主要实现了两个接口

/**
 * Transaction Manager.
 *
 * Define a global transaction and control it.
 */
public interface TransactionManager {

    /**
     * Begin a new global transaction.
     *
     * @param applicationId ID of the application who begins this transaction.
     * @param transactionServiceGroup ID of the transaction service group.
     * @param name Give a name to the global transaction.
     * @param timeout Timeout of the global transaction.
     * @return XID of the global transaction
     * @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown out.
     */
    String begin(String applicationId, String transactionServiceGroup, String name, int timeout) throws TransactionException;

    /**
     * Global commit.
     *
     * @param xid XID of the global transaction.
     * @return Status of the global transaction after committing.
     * @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown out.
     */
    GlobalStatus commit(String xid) throws TransactionException;

    /**
     * Global rollback.
     *
     * @param xid XID of the global transaction
     * @return Status of the global transaction after rollbacking.
     * @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown out.
     */
    GlobalStatus rollback(String xid) throws TransactionException;

    /**
     * Get current status of the give transaction.
     * @param xid XID of the global transaction.
     * @return Current status of the global transaction.
     * @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown out.
     */
    GlobalStatus getStatus(String xid) throws TransactionException;
}
/**
 * Resource Manager: send outbound request to TC.
 */
public interface ResourceManagerOutbound {

    Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid, String lockKeys) throws
        TransactionException;

    void branchReport(String xid, long branchId, BranchStatus status, String applicationData) throws TransactionException;

    boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys) throws TransactionException;
}

涉及到实现的代码细节这里就不多分析。后面尝试用一个完整的例子去把整个流程去说明(锁、事务状态)。
这里需要说明的是整个事务的状态是由TC来进行统一维护的,因此这里会涉及到存储状态的问题。
官方文档提供的版本是本地文件存储FileBasedSessionManager,如果需要线上环境使用还需要自己额外做扩展。比如使用redis或者DB来做存储。

三、请求流程

我在fescar server上增加了输出日志。这样可以更好地了解整个分布式事务的通讯过程。

11:48:38.520 [pool-1-thread-4] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 全局事务[start]...applicationId:dubbo-demo-app,transactionServiceGroup:my_test_tx_group,name:dubbo-demo-tx
11:48:38.522 [pool-1-thread-4] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 全局事务[success]...applicationId:dubbo-demo-app,transactionServiceGroup:my_test_tx_group,name:dubbo-demo-tx,xid:172.19.5.94:8091:2807285
11:48:38.610 [pool-1-thread-6] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[start]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:storage_tbl:9
11:48:38.611 [pool-1-thread-6] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[success]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:storage_tbl:9,branchId:2807286
11:48:38.634 [pool-1-thread-7] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务状态变更[start]...xid:172.19.5.94:8091:2807285,branchId:2807286,status:PhaseOne_Done,applicationData:null
11:48:38.700 [pool-1-thread-9] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[start]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:account_tbl:9
11:48:38.700 [pool-1-thread-9] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[success]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:account_tbl:9,branchId:2807287
11:48:38.717 [pool-1-thread-10] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务状态变更[start]...xid:172.19.5.94:8091:2807285,branchId:2807287,status:PhaseOne_Done,applicationData:null
11:48:38.763 [pool-1-thread-12] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[start]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:order_tbl:19
11:48:38.764 [pool-1-thread-12] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务注册[success]...branchType:AT,resourceId:jdbc:mysql://10.16.6.120:3306/fescar,clientid:172.19.5.94,xid:172.19.5.94:8091:2807285,lockKeyslockKeys:order_tbl:19,branchId:2807288
11:48:38.784 [pool-1-thread-13] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 分支事务状态变更[start]...xid:172.19.5.94:8091:2807285,branchId:2807288,status:PhaseOne_Done,applicationData:null
11:48:38.799 [pool-1-thread-14] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 事务提交[start]...xid:172.19.5.94:8091:2807285
11:48:38.801 [AsyncCommitting_1] INFO com.alibaba.fescar.server.coordinator.DefaultCore - 全局事务提交[start]...transactionId:2807285
11:48:38.835 [AsyncCommitting_1] INFO com.alibaba.fescar.server.coordinator.DefaultCore - Global[2807285] committing is successfully done.

请求流程

事务回滚的流程还要后续补充

三、待续

这两天争取把整个通讯流程梳理清楚。文章待继续完善

四、问题

  1. xid和branch id如何在整个通讯的过程中传递?
  2. 某个事务提交失败/回滚失败如何处理?
  3. xid的生成如何保证唯一。fescar-server的xid生成规则(集群的场景)
  4. lock-key的作用
  5. 事务回滚涉及到回滚sql的生成。fescar能解决ABA的问题吗?
上一篇下一篇

猜你喜欢

热点阅读