基于Tcc分布式事务协议的实现;为什么项目名称叫mule(骡子)呢,因为本项目友好的借鉴(copy)了其他项目的优点;
已经上传到maven中央库:
<dependency>
<groupId>net.lulihu</groupId>
<artifactId>mule-tcc-springcloud</artifactId>
<version>1.0-RELEASE</version>
</dependency>
spring cloud测试版本 是2.0.4.RELEASE,其他版本兼容性未知。
注意:linux 杀死进程的指令 kill -9 可能导致事务丢失。请使用kill -15由操作系统提醒jvm自行关闭(等待当前已经接受的事务记录执行结束在关闭)。
在需要事务确认或回滚的方法上使用MuleTcc注解。
MuleTcc注解参数详解:
String confirmMethod() default ""; 定义事务确认方法,如果事务执行成功则通知所有方法执行事务确认(可不设置既不执行)
String cancelMethod() default ""; 定义事务取消方法,如果事务执行失败则通知所有方法执行事务取消(可不设置既不执行)
boolean currentMethod() default false; 定义事务确认或取消时,是否执行当前方法(默认为不执行),当该参数为true时,confirmMethod()与cancelMethod()将失效
boolean exceptionNotRollBack() default true; 定义事务执行过程中发生错误的方法不进行事务回滚(默认为true不进行回滚,注意:该属性只对Rpc的方法生效)
注意:目前事务确认或取消方法只支持在当前类或当前类的父类中
如下图:
事务方法参数可选的与目标方法一致或者为无参方法,因为执行事务方法是通过方法名称进行寻找的所有方法名称必须一致
普通方法事务注解使用:
Rpc接口方法事务注解使用:
mule-tcc
applicationName -> 应用程序名称用生成指定的事务记录前缀(必须设置否则将导致启动失败)
serializer -> 选择序列化程序。可选参数 [kryo,jdk] 详细见 SerializeEnum对象
scheduledThreadMax -> 自我修复程序最大线程数,默认超过4核的处理器为两个线程,反之一个线程
scheduledDelay -> 自我修复计划修复查询间隔 单位/秒
scheduledInitDelay -> 自我修复计划初始执行延迟时间 单位/秒
retryMax -> 事务提交或取消最多重试次数
recoverTimeInterval -> 重试时间最小间隔 单位/秒 (真实重试时间必定大于或等于此时间)
firstRecoveryTimeInterval -> 事务首次恢复延迟时间 单位/秒
deleteExcessCompensationRecordInitialDelay -> 删除多余补偿记录的初始延迟时间 单位/秒
bufferSize -> 异步线程池 缓冲区大小 (为2的幂次数)
consumerThreadNum -> 异步线程池 消费者线程数量 (默认为处理器核心数的左1移位运算)
repositorySupport -> 事务记录保存存储库支持。可选参数[db] 详细见 RepositorySupportEnum对象
dbConfig: -> 储存库为db时的数据库配置 (使用HikariCP作为数据库连接池)
driverClassName -> 驱动程序全类名
url -> 数据库地址
username -> 账号
password -> 密码
maxActive -> 最大活跃连接 详细介绍参考: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
minIdle -> 最小活跃连接
connectionTimeout -> 数据库连接池中连接的最大超时毫秒数
idleTimeout -> 连接在连接池中最长空闲时间
maxLifetime -> 连接池中连接的最长生命周期
successCode -> 请求成功状态码,当事务处理单位为请求时需要注意此属性(默认状态为200,该参数为集合,可接收多个)
注意: 参数successCode->例如你使用springboot的异常拦截器拦截了所有异常就有可能导致事务方法未拦截到异常,认为执行成功而去执行事务确认方法。 可通过该参数进行设置http返回状态码进行判断执行事务提交还是事务取消方法。(异常拦截器拦截后请返回本次请求的状态码,方便程序判断) 该属性为集成mule-tcc-springcloud组件特有的参数。
非spring cloud的可以参考组件mule-tcc-springcloud中的集成方式,自行集成。 mule-tcc-transaction为核心组件,与其他框架无依赖,简易的使用方式可见demo中的helloword组件。
ComponentService -- 组件顶级接口
MuleTccBootService -- 快速启动组件服务
MuleTccShutdownService -- 组件关闭程序(注册的组件会按指定顺序进行关闭资源)
TransactionSupportService -- 组件选取服务(类似spring的接口参数处理选举)
TransactionCoordinatorService -- 事务协调器服务(协调事务问题为事务产生的事件提供方法)
TransactionCoordinatorRepositoryService -- 事务协调器存储库服务(对事务记录进行落地为协调器提供方法)
TransactionExecutorEventService -- 事务执行事件服务(对事务处理器提供方法)
TransactionHandlerService -- 事务处理器服务(针对不同的事务上下文执行不同的事务处理器)
TransactionMethodProxyService -- 事务方法代理服务(为不污染代码,在进行集成的时候,需要使用该服务对你的代理方法进行环绕通知)
MuleTccTransactionSelfHealingProgram -- 事务自我尝试修复程序(多次重试解决有随机性的bug,例如网络波动等等)
如下
Try:预留业务资源
Confirm:确认执行业务操作
Cancel:取消执行业务操作
稍稍对照下关系型数据库事务的三种操作:
DML、Commit和Rollback,会发现和TCC有异曲同工之妙。 在一个跨应用的业务操作中,
Try操作是先把多个应用中的业务资源预留和锁定住,为后续的确认打下基础,类似的,DML操作要锁定数据库记录行,持有数据库资源;
Confirm操作是在Try操作中涉及的所有应用均成功之后进行确认,使用预留的业务资源,和Commit类似;
Cancel则是当Try操作中涉及的所有应用没有全部成功,需要将已成功的应用进行取消(即Rollback回滚)。
其中Confirm和Cancel操作是一对反向业务操作。
简而言之,如果你将应用看做资源管理器的话,TCC是应用层的2PC(2 Phase Commit, 两阶段提交),
TCC每项操作需要做的事情如下:
1、Try:尝试执行业务。
完成所有业务检查(一致性);
预留必须业务资源(准隔离性)
2、Confirm:确认执行业务。
真正执行业务;
不做任何业务检查;
只使用Try阶段预留的业务资源
3、Cancel:取消执行业务
释放Try阶段预留的业务资源
完整的TCC事务参与方包括三部分: 主业务服务:主业务服务为整个业务活动的发起方,如前面提到的组合支付场景,支付系统即是主业务服务。
从业务服务:从业务服务负责提供TCC业务操作,是整个业务活动的操作方。从业务服务必须实现Try、Confirm和Cancel三个接口,供主业务服务调用。由于Confirm和Cancel操作可能被重复调用,故要求Confirm和Cancel两个接口必须是幂等的。前面的组合支付场景中的余额系统和红包系统即为从业务服务。
业务活动管理器:业务活动管理器管理控制整个业务活动,包括记录维护TCC全局事务的事务状态和每个从业务服务的子事务状态,并在业务活动提交时确认所有的TCC型操作的confirm操作,在业务活动取消时调用所有TCC型操作的cancel操作。 可见整个TCC事务对于主业务服务来说是透明的,其中业务活动管理器和从业务服务各自干了一部分工作。
TCC的优点和限制
TCC事务的优点如下:
解决了跨应用业务操作的原子性问题,在诸如组合支付、账务拆分场景非常实用。 TCC实际上把数据库层的二阶段提交上提到了应用层来实现,对于数据库来说是一阶段提交,规避了数据库层的2PC性能低下问题。
TCC事务的缺点,主要就一个:
TCC的Try、Confirm和Cancel操作功能需业务提供,开发成本高。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型