- 后端
- 微服务
【免费下载链接】incubator-seata
:fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.
本文基于 changes/zh-cn/1.6.0.md 展开,围绕 Seata 1.6.0 发布说明中的 feature、bugfix、optimize、test 四类变更,逐项解析其业务价值与源码实现依据。读完本文,你将掌握该版本的核心能力边界(如多注册中心、多主键、JDK17、update join 联表更新等),理解 InsertOnDuplicateUpdate 系列修复背后的前后镜像机制,以及升级到 1.6.0 时值得关注的兼容性与配置要点。
版本概览:Seata 1.6.0 带来了什么
Seata 1.6.0 是 Seata 分布式事务解决方案在 1.6 系列的第一个正式版本,定位为特性增强 + 大规模缺陷收敛的里程碑版本。本次发布共包含 9 项 feature、34 项 bugfix、24 项 optimize 以及 3 项测试相关改动,覆盖 AT 模式 SQL 解析与前后镜像、TCC 模式注解语义、Server 端注册中心与存储、XA 模式连接处理、客户端 SDK 与构建链等多个层面。
从变更重心看,1.6.0 有三个明显主题:
- 数据库兼容性纵深:Oracle/PostgreSQL 多主键、Oracle timestamp/nclob、MySQL update join 与 InsertOnDuplicateUpdate 系列问题集中修复;
- 接入生态扩展:支持 Apache Dubbo3、Nacos contextPath、JDK17 客户端、Docker arm64 镜像;
- Server 可用性治理:多注册中心、注册中心重启后 accessKey 丢失修复、XA 连接状态回滚修复。
以下按发布说明的四类条目逐一展开。
Feature 详解:九大新特性与源码实现
支持 Oracle 和 PostgreSQL 多主键
在 1.6.0 之前,AT 模式对多主键表的支持主要面向 MySQL;本次更新(PR #4863)将多主键能力扩展到了 Oracle 和 PostgreSQL,使得这两类数据库下基于多个主键列生成前后镜像、构建锁定键(lock key)与执行回滚 SQL 的行为与 MySQL 对齐。
从源码结构看,AT 模式的前后镜像查询与锁键构建统一收敛在 BaseTransactionalExecutor 中,其中buildLockKey(TableRecords rowsIncludingPK)在 1.6.0 中还专门做了可读性重构(见下文 optimize 部分),多主键支持的本质是让 SQL 解析器识别出"多个主键列构成的行唯一性",并据此拼接where pk1 = ? and pk2 = ?形式的镜像查询条件。
seata-server 支持多注册中心
PR #4649 为 seata-server 引入了多注册中心能力,即一个 Server 实例可同时注册到多个注册中心(如 Nacos + Consul),客户端任选其一即可发现服务,适合多机房、多注册中心共存的过渡期或容灾场景。
源码层面,该能力由 MultiRegistryFactory 实现:它读取registry.type配置,通过Constants.REGISTRY_TYPE_SPLIT_CHAR分隔符切分多个类型名,再借助EnhancedServiceLoader按RegistryProvider逐个加载并实例化对应RegistryService,最终返回实例列表List<RegistryService>。配置示例:
registry { # 多注册中心:多个类型用分隔符隔开 type = "nacos,consul" ... }单注册中心场景则仍走 RegistryFactory,两者读取同一registry.type配置项。当前 RegistryType 枚举支持的注册中心类型包括:File、Raft、ZK、Redis、Nacos、Eureka、Consul、Etcd3、Sofa、Custom以及Seata(namingserver)。
支持 Apache Dubbo3
PR #4779 为 Seata 的 Dubbo 集成新增了 Apache Dubbo3(org.apache.dubbo)支持,与既有的seata-dubbo-alibaba(com.alibaba.dubbo)并存。仓库中 extensions/rpc 模块下新增了seata-dubbo目录,内含 Dubbo3 的集成配置与扩展实现;而 extensions/rpc/seata-dubbo-alibaba 继续服务 Alibaba Dubbo 用户。这意味着使用 Dubbo3 的微服务应用可以原生接入 Seata 的全局事务拦截,无需改造 RPC 框架。
TCC 注解支持添加在接口和实现类上
PR #4479 放宽了 TCC 模式@TwoPhaseBusinessAction等注解的标注位置:此前注解一般要求落在实现类方法上,1.6.0 起允许同时标注在接口方法与实现类方法上,提升了与既有代码风格的兼容性——尤其是那些在接口上统一声明业务契约、在实现类中完成业务逻辑的工程。对应逻辑位于 tcc 模块的注解解析与代理构建中,解析时会按"实现类优先、接口兜底"的策略定位两阶段方法。
client SDK 支持 JDK17
PR #4877 让 Seata 客户端 SDK 可以在 JDK 17 运行时环境下正常工作。该项改动同时伴随着多条与 JDK 兼容性相关的修复,例如 PR #4874(OpenJDK 11 启动失败)、PR #5163(高版本 JDK 编译失败),共同保证了从 JDK8 到 JDK17 的平滑过渡。需要注意的是,该支持针对的是client SDK 运行与编译,Server 端运行环境的 JDK 选择仍建议以官方部署文档为准。
支持 MySQL update join 联表更新语法
PR #4914 为 AT 模式补上了 MySQLUPDATE ... JOIN ...联表更新语法的支持。此前此类 SQL 无法被正确识别与拦截,1.6.0 在 SQL 解析层新增了对应执行器 MySQLUpdateJoinExecutor,它继承自UpdateExecutor,负责对联表更新生成正确的前后镜像与 undo log。
支持 Oracle timestamp 类型
PR #4542 使 AT 模式支持 Oracle 的TIMESTAMP类型字段。在此之前,timestamp 类型在镜像比对、值序列化环节可能被当作字符串或无法正确比对,导致回滚数据不一致;1.6.0 起在类型处理层将 timestamp 纳入支持范围。
支持 Nacos contextPath 配置
PR #5111 允许通过配置为 Nacos 注册中心指定contextPath,适配 Nacos 部署在反向代理或自定义上下文路径下的场景。在 NacosRegistryServiceImpl 中,contextPath 的取值顺序为:系统属性优先,其次读取registry.nacos.contextPath配置;配置存在时写入 Nacos 客户端Properties的contextPath属性。对应配置键的拼装见 getNacosContextPathKey,即registry.nacos.contextPath。
Dockerfile 支持 arm64
PR #4802 为 seata-server 的 Docker 镜像构建链路增加了 ARM64 架构支持,并配套新增 ARM64 CI 流水线(PR #4963),使seataio/seata-server镜像可以在 Apple Silicon 等 ARM 平台直接运行。构建配置位于 distribution/docker。
Bugfix 解析:围绕 AT 模式前后镜像的密集修复
1.6.0 的 bugfix 清单高度集中于MySQL InsertOnDuplicateUpdate 语句与update join,这两类 SQL 在 AT 模式中会触发"前镜像查询条件构造""参数占位符计算""后镜像查询""锁键构建"等一系列复杂逻辑,也是 1.6.0 修复的重灾区。
InsertOnDuplicateUpdate 系列问题(约 10 项)
INSERT ... ON DUPLICATE KEY UPDATE(以下简称 IODKU)是 MySQL 特有的写冲突语义,AT 模式要将其正确纳入全局事务,必须先在执行前查询"受影响行"的前镜像。1.6.0 针对该语句的修复包括:
| PR | 修复内容 | 影响 |
|---|---|---|
| #4912 | IODKU 列名大小写不一致时无法匹配 | 前后镜像列映射正确性 |
| #4953 | IODKU 可绕过修改主键的拦截 | 防止通过 IODKU 篡改主键 |
| #5028 | insert 值中的 null 被解析成字符串 | null 值处理 |
| #5031 | 不应使用 null 索引值作为镜像查询条件 | 前镜像查询正确性 |
| #5032 | 条件参数填充位置计算错误导致镜像查询 SQL 异常 | 占位符绑定 |
| #5033 | SQL 中无插入列字段时空指针 | 空列场景兜底 |
| #5075 | 无法拦截无主键和唯一索引的 IODKU SQL | 拦截完备性 |
| #4995 | 后置镜像查询 SQL 中重复的主键查询条件 | 后镜像查询去重 |
| #5078 | 无主键和唯一键的 SQL 无法拦截 | 拦截完备性 |
上述修复的落点集中在 MySQLInsertOnDuplicateUpdateExecutor,该类标注为@LoadLevel(name = JdbcConstants.MYSQL, scope = Scope.PROTOTYPE),即按 MySQL 方言加载。它通过isUpdateFlag区分"新增"与"冲突更新"两条路径,并动态拼接selectSQL作为前后镜像的查询条件(条件取唯一索引)。同一执行器在 mariadb 与 polardbx 方言下也有对应实现。
update join 相关修复
与联表更新特性配套,1.6.0 修复了两处 update join 缺陷:
- PR #5004:修复 update join 场景下行数据重复,导致前镜像/后镜像记录重复的问题;
- PR #5052:修复 update join 条件中占位符参数(
?)与真实参数绑定错位的问题。
这两项直接影响 MySQLUpdateJoinExecutor 在执行UPDATE t1 JOIN t2 ...时的镜像数据保真度。
undo log 与回滚正确性
- PR #4985:修复 undo_log id 重复问题,避免并发/重试场景下 undo log 主键冲突;
- PR #4838:修复使用
Statement.executeBatch()批量执行时无法生成 undo log 的问题; - PR #5051:回滚时若检测到 undo log 对应的数据被脏写,抛出
BranchRollbackFailed_Unretriable异常并停止重试——避免脏写数据下无限重试造成更大的数据不一致。
事件、指标与 Server 状态
- PR #4780:修复超时回滚成功后无法发送
TimeoutRollbacked事件; - PR #4533:修复
handleRetryRollbacking事件重复导致指标数据不准确; - PR #4919:修复 XID 的 port 与 address 在
coordinator.init前出现null:0的问题; - PR #4928:修复
rpcContext.getClientRMHolderMap空指针; - PR #4860:修复 Server 端 metrics tag 覆盖问题。
连接池与数据源代理
- PR #5131:修复 XA 连接处于 active 状态时无法回滚的问题;
- PR #5134:修复 HikariDataSource 自动代理在某些情况下失效的问题;
- PR #5104(optimize 类):
ConnectionProxy脱离对 Druid 的依赖,使数据源代理不再强绑定特定连接池; - PR #5098:Druid 禁用 Oracle implicit cache,规避 Oracle 隐式游标缓存导致的连接状态问题。
配置与启动类修复
- PR #4915:修复获取不到
ServerRecoveryProperties属性的问题; - PR #5093 / #5097:修复 seata-server 重启后 accessKey 丢失问题(两次提交,分别针对不同路径);
- PR #5018:修复启动脚本中 loader path 使用相对路径导致 Server 启动失败的问题;
- PR #4874:修复 OpenJDK 11 启动失败;
- PR #4817:修复高版本 Spring Boot 配置不标准的问题;
- PR #5092:修复 Seata 与 JPA 共用时 AutoConfiguration 顺序不正确的问题;
- PR #5109:修复 RM 侧未加
@GlobalTransactional时报 NPE 的问题——该修复降低了误用场景下的崩溃率,但正确用法仍应在事务入口标注@GlobalTransactional。
序列化与 TCC/Saga
- PR #4978:修复 Kryo 序列化对循环引用的支持;
- PR #4543:修复对 Oracle
NCLOB数据类型的支持; - PR #5038:修复
SagaAsyncThreadPoolProperties冲突问题; - PR #5050:修复 Saga 模式下全局状态未正确更改为
Committed的问题。
Optimize 解析:性能、运维与工程治理
性能与锁
- PR #4681:优化全局事务中竞争锁的检查过程,降低锁竞争开销;
- PR #4761:RedisLocker 中使用
hget替代hmget(仅需单个字段),减少网络与内存开销; - PR #4750:优化 AT 分支释放全局锁时不再使用 xid,减少锁释放的依赖条件;
- PR #4946:获取锁时遇到的 SQL 异常直接传递给客户端,提升问题可诊断性;
- PR #4974:取消 Redis 模式下查询 globalStatus 数量的限制;
- PR #4582:Redis 存储模式支持按超时时间排序(sorted set),优化超时事务的扫描顺序;
- PR #4445:优化事务超时判断逻辑;
- PR #4958:超时事务不再执行
triggerAfterCommit(),避免超时后误提交后置回调。
连接与镜像
- PR #4765:MySQL 8.0.29 及以上版本,XA 模式不再将 connection 持有至二阶段,释放连接资源;
- PR #4836:优化
BaseTransactionalExecutor#buildLockKey(TableRecords rowsIncludingPK)方法可读性; - PR #5104:
ConnectionProxy移除对 Druid 的依赖(见上文)。
构建、发布与安全
- PR #4774 / #4962:优化
seataio/seata-server镜像中的 MySQL8 依赖与基础镜像; - PR #4790:新增自动发布到 OSSRH 的 GitHub Action;
- PR #4807:优化 Docker 镜像与 OSS 仓库发布流水线;
- PR #4797:优化全部 GitHub Actions 脚本;
- PR #4963:新增 ARM64 CI 流水线;
- PR #4800:添加 NOTICE 文件(Apache License V2 合规要求);
- PR #4865 / #4921 / #4917:修复 Saga 可视化设计器 GGEditor、控制台模块的安全漏洞并升级依赖;
- PR #4911:添加 header 与 license 检测工作流。
依赖与代码治理
- PR #4414:移除 log4j 依赖;
- PR #4468:支持 Kryo 5.3.0;
- PR #4932:抽取部分配置的默认值,减少重复硬编码;
- PR #4936:优化存储配置的读取;
- PR #4924 / #4925 / #5047:优化 pom 依赖、javadoc 注释、移除无用代码;
- PR #4490:TCC fence 记录表优化为按索引删除,提升清理效率;
- PR #4981:优化 TCC fence 记录查不到时的错误提示;
- PR #5124:支持 Oracle 删除 TCC fence 记录表;
- PR #4434:移除 seata-server 的 CMS GC 参数(CMS 已在 JDK14+ 被移除,此举适配高版本 JDK)。
Test 与质量保障
1.6.0 的测试工作聚焦在数据库兼容性验证上:
- PR #4411:新增 Oracle 数据库 AT 模式下类型支持的单元测试;
- PR #4794:重构并尝试修复
DataSourceProxyTest.getResourceIdTest(); - PR #5101:修复 ZK 注册与配置中心测试中的
ClassNotFoundException。
配合 ARM64 CI 流水线(PR #4963),1.6.0 形成了"多数据库(MySQL/Oracle/PostgreSQL)+ 多架构(x86/ARM)+ 多注册中心"的测试矩阵雏形。
升级与使用建议
- 关注 InsertOnDuplicateUpdate 与 update join 行为变化:如果业务大量使用 MySQL IODKU 或联表更新,1.6.0 修复了该路径下前后镜像的多处缺陷,升级后事务拦截行为会更严格(例如无主键/唯一索引的 IODKU 将被拦截),需结合 MySQLInsertOnDuplicateUpdateExecutor 的行为提前梳理存量 SQL;
- 多注册中心配置:若需同时注册到多个注册中心,将
registry.type配置为以分隔符连接的多个类型(如"nacos,consul"),参考 MultiRegistryFactory 的加载逻辑; - Nacos 部署在自定义上下文路径时:配置
registry.nacos.contextPath即可适配; - JDK 版本:1.6.0 客户端 SDK 支持至 JDK17,且修复了 OpenJDK11 启动与高版本 JDK 编译问题,升级 JDK 的阻力显著降低;
- 回滚行为变化:undo log 脏写将抛出不可重试异常(PR #5051),运维侧应关注回滚失败日志中该异常的出现,它意味着业务数据已被外部修改,需人工介入而非依赖自动重试。
总结
Seata 1.6.0 是一次"兼容性补全 + 稳定性收敛"的典型版本:新特性聚焦数据库方言(Oracle/PostgreSQL 多主键、MySQL update join、Oracle timestamp)与接入生态(Dubbo3、Nacos contextPath、JDK17、ARM64);修复与优化则系统性地清除了 AT 模式在 IODKU、update join 等高频复杂 SQL 上的前后镜像缺陷,并同步治理了 Server 端的事件、指标、存储与构建链路。对于使用 MySQL 写冲突语义、联表更新或运行于多注册中心/多架构环境的 Seata 用户,1.6.0 具备明确的升级价值。
- 后端
- 微服务
【免费下载链接】incubator-seata
:fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.
相关推荐
Seata 2.0.0 版本发布详解:分布式事务新特性、关键修复与升级实践指南
Seata 2.0.0 版本发布详解:分布式事务新特性、关键修复与升级实践指南 Seata 2.0.0 是 Seata 分布式事务解决方案在 2.x 时代的首个
后端微服务Sphinx 1.2 版本演进全解析:从 1.2 beta1 到 1.2.3 的关键特性与修复
Sphinx 1.2 版本演进全解析:从 1.2 beta1 到 1.2.3 的关键特性与修复 本篇技术指南以 Sphinx 仓库中 doc/changes/1
文档开发工具esbuild 版本演进指南:从 CHANGELOG 解读 0.28.x 的关键修复、安全加固与新特性
esbuild 版本演进指南:从 CHANGELOG 解读 0.28.x 的关键修复、安全加固与新特性 esbuild(An extremely fast bu
构建工具前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考