DDK Seata Starter
基于 Seata 的分布式事务。DDK 额外补上 Seata 缺的一半:出站 HTTP 调用携带全局事务 XID,下游服务才能加入同一个全局事务。
能做什么
text
order-service inventory-service
@GlobalTransactional placeOrder
RootContext.getXID() = 10.0.0.1:8091:42
inventoryClient.post("/deduct")
XidPropagationInterceptor (DDK)
TX_XID: 10.0.0.1:8091:42 ──── HTTP ────► JakartaTransactionPropagationInterceptor (Seata)
RootContext.bind(xid)
deduct() 登记在同一个全局事务下Seata 只处理入站:从 TX_XID 请求头取出 XID 绑定到当前线程。出站调用不带这个头时,下游在全局事务之外各自提交,全局回滚撤不回来,而且没有任何报错。
| 能力 | 提供方 |
|---|---|
数据源代理(AT 模式)、@GlobalTransactional 扫描 | seata-spring-boot-starter |
| 入站请求绑定 XID | seata-spring-boot-starter |
出站 RestClient / RestTemplate 携带 XID | 本 starter |
引入方式
xml
<dependency>
<groupId>com.ddk</groupId>
<artifactId>ddk-seata-starter</artifactId>
<version>${ddk.version}</version>
</dependency>传递引入 seata-spring-boot-starter(版本由根 pom 管理)与 spring-boot-starter-jdbc。Seata 自身用 seata.* 配置:
yaml
seata:
application-id: order-service
tx-service-group: default_tx_group
service:
vgroup-mapping:
default_tx_group: default
grouplist:
default: 127.0.0.1:8091从容器注入 builder 构建 HTTP 客户端,拦截器自动生效:
java
@Bean
RestClient inventoryClient(RestClient.Builder builder) {
return builder.baseUrl("http://inventory-service").build();
}配置项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ddk.seata.http-propagation.enabled | boolean | true | 出站 RestClient / RestTemplate 调用是否携带 TX_XID |
seata.enabled | boolean | true | Seata 自身的开关,关闭时 DDK 的补充一并关闭 |
装配条件与降级行为
- 自动配置类:
com.ddk.seata.starter.config.DdkSeataAutoConfiguration。 - 条件:classpath 有 Seata、
seata.enabled不为false;HTTP 传播还要求 classpath 有spring-web且ddk.seata.http-propagation.enabled不为false。 - 注册
RestClientCustomizer与RestTemplateCustomizer,挂到容器提供的RestClient.Builder/RestTemplateBuilder上。 - 只在全局事务内写头;调用方显式设置了
TX_XID时不覆盖。请求头名取RootContext.KEY_XID,与 Seata 入站拦截器是同一个常量。
不适用的场景 / 已知问题
- 绕过 builder 创建的客户端不传播。
new RestTemplate()、RestClient.create()、手写的HttpClient需要自己加XidPropagationInterceptor。 - 只覆盖
RestClient/RestTemplate。WebClient、OpenFeign、消息队列的 XID 传播没有提供。 - Seata 核心 Bean 没有单元测试覆盖。
GlobalTransactionScanner依赖spring.factories里的ApplicationContextInitializer,ApplicationContextRunner不执行它;数据源代理与真实回滚需要@SpringBootTest加可达的 TC 做集成测试。 - 与 DDK DB Starter 的组合未验证。Seata 的数据源自动代理会作用于容器里所有
DataSource,多数据源场景下的行为没有测试覆盖。 - XA / TCC / SAGA 模式没有额外辅助,模式选择与补偿逻辑由业务自己实现。