fescar源码分析2
一、概要
今天开始重点分析TC和RM的通讯方式。涉及到的核心类
- DefaultCoordinator
- DefaultCore
- ConnectionProxy
- SessionManager
其中涉及到TC的灾备、锁等核心实现。
二、TC核心实现
DefaultCoordinator,事务协调器,简称TC,核心实现在DefaultCore这个类里面。
DefaultCore主要实现了两个接口
- TransactionManager
- ResourceManagerOutbound
TransactionManager,简称TM,事务管理器。把事务实现的通用的接口抽象。主要是TM和TC的通讯接口逻辑
ResourceManagerOutbound,RM和TC通讯的接口。
/**
* 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.
事务回滚的流程还要后续补充
三、待续
这两天争取把整个通讯流程梳理清楚。文章待继续完善
四、问题
- xid和branch id如何在整个通讯的过程中传递?
- 某个事务提交失败/回滚失败如何处理?
- xid的生成如何保证唯一。fescar-server的xid生成规则(集群的场景)
- lock-key的作用
- 事务回滚涉及到回滚sql的生成。fescar能解决ABA的问题吗?