Seata XA 模式理论学习、使用及注意事项 | Spring Cloud54

一、前言

通过以下系列章节:

docker-compose 实现Seata Server高可用部署 | Spring Cloud 51

Seata AT 模式理论学习、事务隔离及部分源码解析 | Spring Cloud 52

Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53

我们对Seata及其AT事务模式的理论、使用有了深入的了解,今天继续对SeataXA事务模式进行理论学习。

理论部分来自Seata官网:http://seata.io/zh-cn/docs/dev/mode/xa-mode.html

二、前提

  • 支持XA 事务的数据库。
  • Java 应用,通过 JDBC 访问数据库。

三、整体机制

Seata 定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种 事务模式

在这里插入图片描述

  • 执行阶段:

    • 可回滚:业务 SQL 操作放在 XA 分支中进行,由资源对 XA 协议的支持来保证 可回滚
    • 持久化:XA 分支完成后,执行 XA prepare,同样,由资源对 XA 协议的支持来保证 持久化(即,之后任何意外都不会造成无法回滚的情况)
  • 完成阶段:

    • 分支提交:执行 XA 分支的 commit
    • 分支回滚:执行 XA 分支的 rollback

目前 SeataXA 模式分支注册的时机需要在 XA start 之前,详见 4.2章节 分支注册

四、工作机制

4.1 数据源代理

XA 模式需要 XAConnection

获取 XAConnection 两种方式:

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

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

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

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

类比 AT 模式的数据源代理机制,如下:

在这里插入图片描述

但是,第二种方法有局限:无法保证兼容的正确性。

实际上,这种方法是在做数据库驱动程序要做的事情。不同的厂商、不同版本的数据库驱动实现机制是厂商私有的,我们只能保证在充分测试过的驱动程序上是正确的,开发者使用的驱动程序版本差异很可能造成机制的失效。

这点在 Oracle 上体现非常明显。

综合考虑,XA 模式的数据源代理设计需要同时支持第一种方式:基于 XA 数据源进行代理。

类比 AT 模式的数据源代理机制,如下:

在这里插入图片描述

4.2 分支注册

XA start 需要 Xid 参数。

这个 Xid 需要和 Seata 全局事务的 XIDBranchId 关联起来,以便由 TC 驱动 XA 分支的提交或回滚。

目前 SeataBranchId 是在分支注册过程,由 TC 统一生成的,所以 XA 模式分支注册的时机需要在 XA start 之前。

将来一个可能的优化方向:
把分支注册尽量延后。类似 AT 模式在本地事务提交之前才注册分支,避免分支执行失败情况下,没有意义的分支注册。
这个优化方向需要 BranchId 生成机制的变化来配合。BranchId 不通过分支注册过程生成,而是生成后再带着 BranchId 去注册分支。

五、XA 模式的使用

从编程模型上,XA 模式与 AT 模式保持完全一致。

通过以下配置实现 AT 模式向 XA 模式的切换:

seata:
  enabled: true
  enable-auto-data-source-proxy: true
  data-source-proxy-mode: XA

AT 模式完整示例请见上期章节:Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53

猜你喜欢

转载自blog.csdn.net/ctwy291314/article/details/130930710