这是我参与「第四届青训营 」笔记创作活动的第18天

45 阅读2分钟

分布式事务

以一个用户购买商品的业务逻辑为例。

由于整个项目随着业务需求的增加,由原来的单体应用,拆分成了多个微服务应用:

  • 仓储服务:对给定的商品扣除仓储数量。
  • 订单服务:根据采购需求创建订单。
  • 帐户服务:从用户帐户中扣除余额。

此时每个服务内部的数据一致性只能由本地的事务保证,但是对于全局(服务间)数据一致性问题没办法保证。

全局事务包含若干分支(本地)事务,并统一协调分支事务达成一致,同一全局事务下的分支事务,要么一起提交,要么一起回滚。

全局数据一致性的产生就是一次业务操作需要处理多个数据源,这时就产生了分布式事务问题。

Seata 组件

TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

Seata-Client 数据库

Seata 的客户端使用与官方示例相同的三个服务:

  • seata-account-service:账户服务
  • seata-order-service:订单服务
  • seata-storage-service:库存服务

获取 XAConnection 两种方式:

  • 方式一:要求开发者配置 XADataSource;
  • 方式二:根据开发者的普通 DataSource 来创建;

第一种方式,给开发者增加了认知负担,需要为 XA 模式专门去学习和使用 XA 数据源,与 透明化 XA 编程模型的设计目标相违背。

第二种方式,对开发者比较友好,和 AT 模式使用一样,开发者完全不必关心 XA 层面的任何问题,保持本地编程模型即可。

方式二实现思路与 AT 模式相同,参考示例实现即可。

注:需要把配置文件 application.properties 中的模式配置修改为:seata.data-source-proxy-mode=XA

我们优先设计实现第二种方式:数据源代理根据普通数据源中获取的普通 JDBC 连接创建出相应的 XAConnection。