分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。例如在大型电商系统中,下单接口通常会扣减库存、减去优惠、生成订单 id, 而订单服务与库存、优惠、订单 id 都是不同的服务,下单接口的成功与否,不仅取决于本地的 db 操作,而且依赖第三方系统的结果,这时候分布式事务就保证这些操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务的解决方案
两阶段提交/XA
TCC
本地消息表
可靠消息最终一致性
尽最大努力通知
参考文献
在分库分表的情况下,由于操作多个库,此时就涉及到分布式事务。例如执行一个批量插入SQL,如果记录要插入到不同的库中,就无法保证一致性。因此,通常情况下,数据库中间件,只会保证单个库的事务,也就是说,业务方在创建一个事务的时候,必须要保证事务中的所有操作,必须最终都在一个库中执行。 事实上,在微服务的架构下,事务的问题更加复杂,如下图:
Service A 在执行某个操作时,需要操作数据库,同时调用 Service B 和 Service C,Service B 底层操作的数据库是分库分表的,Service C 也要操作数据库。 这种场景下,保证事务的一致性就非常麻烦。一些常用的一致性算法如:paxos协议、raft协议也无法解决这个问题,因为这些协议都是资源层面的一致性。在微服务架构下,已经将事务的一致性上升到了业务的层面。
如果仅仅考虑分库分表,那么可以使用 XA,但是性能很差,对数据库的版本也有要求,例如必须使用 MySQL 5.7,官方还建议将事务隔离级别设置为串行化,这是无法容忍的。
由于分布式事务的应用场景并不是仅仅分库分表,因此通常都是会有一个专门的团队来做分布式事务,并不一定是数据库中间件团队来做。例如,sharding-jdbc 就使用了华为开源的一套微服务架构解决方案 service comb 中的 saga 组件,来实现分布式事务最终一致性。
阿里也有类似的组件,在内部叫 TXC,在阿里云上叫 GTS,最近开源到了 GitHub 上叫 fescar(Fast & Easy Commit And Rollback)。
蚂蚁金服也有类似的组件,叫 DTX,支持 FMT 模式和 TCC 模式。其中 FMT 模式就类似于 TXC。