标签:content 结果 数据源 sof eth prot LLC 第一个 hub
EasyTransaction是一个全功能的分布式事务框架,以下特性摘抄自其首页:https://github.com/QNJR-GROUP/EasyTransaction
本文主要分享EasyTransaction core中各个package的作用其主要实现。
请先阅读 Seata架构的比对思考 https://www.cnblogs.com/skyesx/p/10674700.html ,再结合 代码以及demo调试过程看这篇,直接看的话这里的点太零碎了
主要类
LogProcessContext
其用于存储ET事务的上下文信息。在开启ET事务(第一次ET远程调用,或者主动调用startSoftTrans方法)时,将创建本类的实例并将其与Spring的本地事务上下文绑定,通过:
TransactionSynchronizationManager.bindResource()
执行绑定。当需要取得ET上下文时,通过
TransactionSynchronizationManager.getResource()
取得。
ET上下文中包含的主要内容有:
本包主要类为
EasyTransFacade
TransactionHook
ConsistentGuardian
ExecuteCacheManager
其定义了业务调用方的接口,只包含两个:
public void startEasyTrans(String busCode,long trxId);
public <P extends EasyTransRequest<R,E>,E extends EasyTransExecutor, R extends Serializable> Future<R> execute(P params);
第一个用于开启全局事务,主要的操作为:
第二个表示执行某个远程事务方法。
基于注解的接口调用也是通过这两个方法封装而成。
其为ET框架代码与Spring原生事务的主要交界点,ET通过TransactionSynchronization定义的方法,在Spring本地事务执行过程中,扩展支持了全局事务。主要扩展了以下两个方法
beforeCommit(boolean readOnly)
afterCompletion(int status)
beforeCommit方法将会
afterCompletion方法将会
本类用于处理ET全局事务的最终一致,例如TCC的Conifrim/Cancel,可靠消息的发送消息。
最终一致处理通常会在同步操作(TCC的TRY等)对应的本地事务执行完成后抛到线程池异步执行,但执行失败的话,会有兜底的补偿(recovery包),后续再详细讲述
该类的主要工作机制是根据之前写入的全局事务日志,获取日志对应的处理器(如从TCC的事务日志获取对应的TCC日志处理器),以此
本类主要服务于ET的以下期望
其主要实现的是,
主要包含以下两个接口,其主要作用于业务数据源。
DataSourceSelector
TransStatusLogger
该类主要用于获取当前事务/请求对应的数据源及其事务管理器,若应用有多个业务数据源,则需要自行实现对应的数据源选择器,主要包含以下方法
DataSource selectDataSource(String appId,String busCode,long trxId);
DataSource selectDataSource(String appId,String busCode,EasyTransRequest<?, ?> request);
第一个方法是开启ET事务时候选择对应的数据源
第二个方法是被调用方接受到请求时选择对应的数据源(用于幂等、防悬挂处理,若不需要可忽略)
该接口包含一个默认实现,当只有单数据源时,可以直接用该实现
SingleDataSourceSelector
该类主要用来读写用于判断ET事务状态的记录,该记录会在ET事务开启时,写入当前的数据库表中,随着业务对应事务(Spring本地事务)提交而提交,回滚而回滚。
更具体请直接看实现
该包存储的是事务发起方(远程服务调用方)相关处理类的位置,不同的事务类型(TCC,可靠事务等)有不同的Executor,以TCC为例讲解,其他的事务类型实现都类似。
该类实现了三个接口
EasyTransExecutor接口定义了方法
<P extends EasyTransRequest<R,E>,E extends EasyTransExecutor,R extends Serializable> Future<R> execute(Integer sameBusinessCallSeq, P params);
该方法供类EasyTransFacade.execute使用,其对应的是执行TCC里的TRY方法,具体的,它
LogProcessor接口定义了如何处理事务日志,其包含一个主要方法
boolean logProcess(LogProcessContext ctx, Content currentContent)
该方法将会判断,如果传入的日志类型是PreTccCallContent(TCC TRY请求对应的日志)的话,将会监听该日志最终的配对信息(类ConsistentGuardian会在处理当前ET事务的日志后,发送消息,告知所有需要配对的日志的配对结果),如果
其他的事务形态的实现也类似,不再赘述
用于兜底恢复事务,实现最终一致。
代码不复杂,可以自行查看。
该包主要用于实现ET对应的Filter,该Filter作用于被调用端。我们可以通过实现ET的Filter扩展被调用端的功能,如处理幂等、处理嵌套事务、增加调用上下文的处理等等。
实现幂等、方悬挂等处理对应的包
幂等及防悬挂处理的主要原理:
用于生成ET的分布式事务ID,当自行制定ID时,本包对应的方法不会被调用。当不指定ID时,将会自动生成一个。
定义ET事务日志对应的Class,以及其读写接口。
事务日志在之前TccExecutor等章节已提到,不再赘述。
需要扩展事务日志存储实现的,直接实现以下接口即可
TransactionLogReader
TransactionLogWritter
(ET事务日志的读写不需要与业务事务在同一个事务中,也不能在同一个事务中)
用于在同一个appId中选择一个作为master进行兜底最终一致补偿的包。
实际上选择不需要太精确,任意一个appId下的实例均可,也可以同时有多个master存在(但目前没有意义,也会浪费性能)
用于提供ET实例状态的包,可供Dashboard,监控等扩展使用
供客户直接定义分布式事务服务的包,其包含一些客户直接使用的 父类、配置接口、配置注解等
从Spring中获取并存储对应的bean实现,以便于快速方便地通过ET对应的定义,取得对应bean
若要扩展新增对应的消息队列实现,则实现这个包对应的接口
同上
ET框架所使用的序列化形式,可自行扩展
用于压缩字符串,将字符串替换为数字id,以提高存储效率
标签:content 结果 数据源 sof eth prot LLC 第一个 hub
原文地址:https://www.cnblogs.com/skyesx/p/11111726.html