工作机制
整体运行机制
XA 模式 运行在 Seata 定义的事务框架内:
- 执行阶段(E xecute):
- XA start/XA end/XA prepare + SQL + 注册分支
- 完成阶段(F inish):
- XA commit/XA rollback
数据源代理
XA 模式需要 XAConnection。
获取 XAConnection 两种方式:
- 方式一:要求开发者配置 XADataSource
- 方式二:根据开发者的普通 DataSource 来创建
第一种方式,给开发者增加了认知负担,需要为 XA 模式专门去学习和使用 XA 数据源,与 透明化 XA 编程模型的设计目标相违背。
第二种方式,对开发者比较友好,和 AT 模式使用一样,开发者完全不必关心 XA 层面的任何问题,保持本地编程模型即可。
我们优先设计实现第二种方式:数据源代理根据普通数据源中获取的普通 JDBC 连接创建出相应的 XAConnection。
类比 AT 模式的数据源代理机制,如下:
但是,第二种方法有局限:无法保证兼容的正确性。
实际上,这种方法是在做数据库驱动程序要做的事情。不同的厂商、不同版本的数据库驱动实现机制是厂商私有的,我们只能保证在充分测试过的驱动程序上是正确的,开发者使用的驱动程序版本差异很可能造成机制的失效。
这点在 Oracle 上体现非常明显。参见 Druid issue:https://github.com/alibaba/druid/issues/3707
综合考虑,XA 模式的数据源代理设计需要同时支持第一种方式:基于 XA 数据源进行代理。
类比 AT 模式的数据源代理机制,如下:
分支注册
XA start 需要 Xid 参数。
这个 Xid 需要和 Seata 全局事务的 XID 和 BranchId 关联起来,以便由 TC 驱动 XA 分支的提交或回滚。
目前 Seata 的 BranchId 是在分支注册过程,由 TC 统一生成的,所以 XA 模式分支注册的时机需要在 XA start 之前。
将来一个可能的优化方向:
把分支注册尽量延后。类似 AT 模式在本地事务提交之前才注册分支,避免分支执行失败情况下,没有意义的分支注册。
这个优化方向需要 BranchId 生成机制的变化来配合。BranchId 不通过分支注册过程生成,而是生成后再带着 BranchId 去注册分支。
XA 模式的使用
我们从官方案例入手,具体的官方案例下载地址:https://github.com/seata/seata-samples
官方案例演示图:
案例解析:
官方案例演示
样例场景是 Seata 经典的,涉及库存、订单、账户 3 个微服务的商品订购业务。
前提:Nacos 和将Seata-Server为正常启动状态
- 首先,我们下载官方使用案例,选择1.4.2分支进行下载
- 使用IDEA打开项目,找到seata-xa服务,使用maven-install进行项目编译
- 业务梳理
business-xa服务:
我们打开BusinessService文件,找到purchase方法
stock-xa服务:
我们打开StockService文件,找到deduct方法
order-xa服务:
我们打开OrderService文件,找到create方法,里面除了生成订单,还有调用账户的方法
account-xa服务:
我们打开AccountService文件,找到reduce方法,里面有扣除账户余额
- 配置说明
下载的项目是官方默认的测试数据库,可以直接使用,也可以修改成本地数据库,如果修改成本地数据库连接,对于的sql文件为all_in_one.sql,本次演示就不做修改直接使用官方测试数据库。
在样例中,上层编程模型与 AT 模式完全相同。只需要修改数据源代理,即可实现 XA 模式与 AT 模式之间的切换。例如:订单服务order-xa中的配置类里面,选择XA模式的代理类
- 演示结果
首先,我们将服务跑起来,演示正常的结果
接着我们访问http://localhost:8084/purchase
此时,我们可以看到stock_tbl表中count从100变成了70,order_tbl表中新增了一条订单记录,account_tbl表中账户余额从10000变成了7000
接着,我们修改订单服务order-xa服务的OrderService文件,找到create方法,添加异常,并在此处打上断点,然后使用Debug模式重跑服务,然后再次访问http://localhost:8084/purchase
此时我们先看数据库的三张表,发现进入断点时的数据库的三张表没有任何变化
最后我们放行断点,服务出现异常,然后我们再来看三张表,发现还是无任何变化。此时我们就验证了XA事务的执行过程
总结
在当前的技术发展阶段,不存一个分布式事务处理机制可以完美满足所有场景的需求。
一致性、可靠性、易用性、性能等诸多方面的系统设计约束,需要用不同的事务处理机制去满足。
Seata 项目最核心的价值在于:构建一个全面解决分布式事务问题的标准化平台。
基于 Seata,上层应用架构可以根据实际场景的需求,灵活选择合适的分布式事务解决方案。
XA 模式的加入,补齐了 Seata 在 全局一致性 场景下的缺口,形成 AT、TCC、Saga、XA 四大事务模式的版图,基本可以满足所有场景的分布式事务处理诉求。