06、分布式事务 实战 - 开源分布式事务Seata

2019年1月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案。Fescar 的愿景是让分布式事务的使用像本地事务的使用一样,简单和高效,并逐步解决开发者们遇到的分布式事务方面的所有难题。Fescar 开源后,蚂蚁金服加入 Fescar 社区参与共建,并在 Fescar 0.4.0 版本中贡献了 TCC 模式。

2019年3月,对 Fescar 进行品牌升级,并更名为 Seata,意为:Simple Extensible Autonomous Transaction Architecture,是一套一站式分布式事务解决方案。

蚂蚁金服内部大量使用TCC解决跨服务事务问题,TCC是一种高性能灵活的事务解决方案,支持了蚂蚁金服双十一的高性能需求,支持了异地多活的高可用需求;此外,为了让分布式事务使用更加便捷,我们推出AT、XA 两种无侵入的事务解决方案;当前蚂蚁的分布式事务解决方案主要有TCC、AT和XA 三种模式,丰富的模式覆盖了分布式事务的各类使用场景。

蚂蚁金服分布式事务经过12年的发展和演进,积累了TCC、AT、XA 三种使用模式,有丰富的应用场景,在高性能和高用方面也有大量实践经验;开源产品Seata中将逐步集成 AT、TCC、和XA三种模式,目前已经有了AT和TCC模式,XA也已规划。

AT模式

 

步骤:

1、 TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID;
2、 XID在微服务调用链路的上下文中传播;
3、 RM向TC注册分支事务,将其纳入XID对应全局事务的管辖;
4、 TM向TC发起针对XID的全局提交或回滚决议;
5、 TC调度XID下管辖的全部分支事务完成提交或回滚请求;

Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚,这个组件需要独立部署维护。
Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

虽然是二阶段提交协议的分布式事务,但是其解决了上面XA的一些缺点:

单点问题:

虽然目前还是单server的,但是官方预计将会在0.5.x中推出HA-Cluster,到时候就可以解决单点问题。

同步阻塞:

在第一阶段的时候本地事务就已经提交释放资源了,不会像XA会再两个prepare和commit阶段资源都锁住,并且Seata,commit是异步操作,也是提升性能的一大关键。

数据不一致:

如果出现部分commit失败,那么Seata-server会根据当前的事务模式和分支事务的返回状态的结果来进行不同的重试策略。并且fescar的本地事务会在一阶段的时候进行提交,其实单看数据库来说在commit的时候数据库已经是一致的了。

只能用于单一数据库: Seata提供了两种模式,AT和MT。在AT模式下事务资源可以是任何支持ACID的数据库,在MT模式下事务资源没有限制,可以是缓存,可以是文件,可以是其他的等等。当然这两个模式也可以混用。

TCC模式

Seata 框架把每组 TCC 接口当做一个 Resource,称为 TCC Resource。这套 TCC 接口可以是 RPC,也可以是服务内 JVM 调用。在业务启动时,Seata 框架会自动扫描识别到 TCC 接口的调用方和发布方。如果是 RPC 的话,就是 sofa:reference、sofa:service、dubbo:reference、dubbo:service 等。
扫描到TCC 接口的调用方和发布方之后。如果是发布方,会在业务启动时向 TC 注册 TCC Resource,与 DataSource Resource 一样,每个资源也会带有一个资源 ID。
如果是调用方,Seata 框架会给调用方加上切面,与 AT 模式一样,在运行时,该切面会拦截所有对 TCC 接口的调用。每调用一次 Try 接口,切面会先向 TC 注册一个分支事务,然后才去执行原来的 RPC 调用。当请求链路调用完成后,TC 通过分支事务的资源 ID 回调到正确的参与者去执行对应 TCC 资源的 Confirm 或 Cancel 方法。

TCC具体实现方法跟之前的TCC类似:

1、 初步操作Try:完成所有业务检查,预留必须的业务资源;
2、 确认操作Confirm:真正执行的业务逻辑,不做任何业务检查,只使用Try阶段预留的业务资源因此,只要Try操作成功,Confirm必须能成功另外,Confirm操作需满足幂等性,保证一笔分布式事务能且只能成功一次;
3、 取消操作Cancel:释放Try阶段预留的业务资源同样的,Cancel操作也需要满足幂等性;

Seata 项目地址:
https://github.com/seata/seata

目前规划: