当前位置: 首页 > backend >正文

分布式事务,事务失效,TC事务协调者


1. 概述

本方案书旨在解决分布式系统中事务一致性问题,重点阐述全局事务标识(XID)的传递与存储机制、事务协调者(TC)的设计与部署,以及分布式事务失效场景的应对策略。基于业界成熟框架(如Seata)的最佳实践,提供高可用、高性能的分布式事务解决方案。


2. 核心概念与架构

2.1 分布式事务模型

  • AT模式(自动补偿)
    通过全局锁和逆向SQL(undo log)实现自动回滚,适用于数据库操作。
  • TCC模式(手动补偿)
    业务层实现Try-Confirm-Cancel接口,适用于复杂业务逻辑。
  • Saga模式(长事务)
    通过事件驱动和补偿事务链实现最终一致性,适用于跨服务长流程。

2.2 核心组件

组件角色
事务协调者(TC)独立服务,负责全局事务状态管理和协调。
事务管理器(TM)集成在业务服务中,负责开启/提交/回滚全局事务。
资源管理器(RM)管理本地资源(如数据库、消息队列),执行分支事务的提交/回滚。

3. XID 的传递与存储机制

3.1 XID 的生成与作用

  • 全局唯一性:由TC生成,格式示例:192.168.1.100:8091:123456
  • 核心功能:关联所有分支事务,确保跨服务、跨资源的操作原子性。

3.2 XID 的传递方式

场景1:跨服务调用(RPC/HTTP)
  • 隐式传递(推荐)
    通过RPC框架(如Dubbo、Feign)的请求头自动传递XID。
    // Feign 拦截器示例  
    public class XidFeignInterceptor implements RequestInterceptor {  @Override  public void apply(RequestTemplate template) {  String xid = RootContext.getXID();  template.header("TX_XID", xid);  }  
    }  
    
场景2:异步任务与多线程
  • 手动传递(基础方案)
    显式传递XID并在子线程中绑定:
    String xid = RootContext.getXID();  
    executor.submit(() -> {  RootContext.bind(xid);  try {  // 业务逻辑  } finally {  RootContext.unbind();  }  
    });  
    
  • TransmittableThreadLocal(推荐)
    使用阿里开源工具解决线程池上下文传递问题:
    private static TransmittableThreadLocal<String> XID = new TransmittableThreadLocal<>();  
    executor.submit(TtlRunnable.get(() -> {  // 子线程自动继承XID  
    }));  
    
场景3:消息队列(如Kafka、RocketMQ)
  • 消息头传递
    生产者将XID写入消息属性,消费者读取后绑定到本地事务:
    // RocketMQ 生产者  
    Message msg = new Message();  
    msg.putUserProperty("XID", xid);  
    

3.3 XID 的存储管理

  • 默认存储:基于ThreadLocal,仅限当前线程访问。
    public class RootContext {  private static ThreadLocal<String> XID = new ThreadLocal<>();  
    }  
    
  • 扩展方案
    • InheritableThreadLocal:支持父子线程传递,但不适用于线程池。
    • TransmittableThreadLocal:支持线程池场景,需配合TtlRunnable使用。

4. 事务协调者(TC)的设计与部署

4.1 TC 的核心职责

  • 全局事务管理:注册XID,维护global_table(全局事务状态表)。
  • 分支事务协调:记录branch_table(分支事务表),驱动提交/回滚。
  • 故障恢复:检测超时事务,触发自动回滚或重试。

4.2 部署模式

独立服务部署(推荐)
  • 启动命令
    # Seata TC 服务启动  
    sh seata-server.sh -p 8091 -m db -h 192.168.1.100  
    
  • 高可用设计
    • 数据库模式:多个TC节点共享同一数据库(如MySQL)。
    • Raft模式:通过一致性协议实现集群选举(Seata 1.5+)。
配置文件示例(Seata)
# registry.conf  
registry {  type = "nacos"  nacos {  serverAddr = "localhost:8848"  namespace = ""  cluster = "default"  }  
}  config {  type = "nacos"  nacos {  serverAddr = "localhost:8848"  namespace = ""  group = "SEATA_GROUP"  }  
}  

4.3 事务恢复流程

  1. 回滚触发:TM通知TC回滚指定XID。
  2. 分支查询:TC从branch_table查询所有关联分支。
  3. 逆向执行:各RM根据undo_log执行补偿操作。

5. 分布式事务失效场景与解决方案

5.1 常见失效场景

场景原因后果
RPC调用未透传XID未在请求头中添加XID下游服务无法加入全局事务
异步任务未绑定XID子线程未继承ThreadLocal中的XID异步操作游离于事务外
TC单点故障未部署TC集群全局事务无法协调

5.2 解决方案

场景1:XID传递失败
  • 强制校验:在事务入口拦截请求,校验XID是否存在。
  • 统一拦截器:通过RPC拦截器(如Spring AOP)自动透传XID。
场景2:多线程XID丢失
  • TransmittableThreadLocal:结合线程池包装类(TtlExecutors)传递上下文。
  • 框架集成:Spring异步任务支持:
    @Configuration  
    @EnableAsync  
    public class AsyncConfig implements AsyncConfigurer {  @Override  public Executor getAsyncExecutor() {  return TtlExecutors.getTtlExecutor(Executors.newFixedThreadPool(4));  }  
    }  
    
场景3:TC单点故障
  • 集群部署:部署多个TC节点,通过Nacos或Raft协议实现高可用。
  • 健康检查:集成Prometheus监控TC节点状态。

6. 最佳实践与性能优化

6.1 最佳实践

  1. 避免跨事务异步操作:将异步任务放在事务边界外。
  2. 事务粒度控制:单个事务内操作不超过3个服务。
  3. 超时配置:全局事务超时时间建议为60秒,避免资源长时间锁定。

6.2 性能优化

  • 异步提交:Seata AT模式下,二阶段提交异步化(默认开启)。
  • 全局锁优化:减少热点数据竞争,使用SELECT ... FOR UPDATE时指定索引。

6.3 监控与日志

  • 监控指标
    • TC节点状态(活跃事务数、TPS)。
    • RM资源锁竞争情况。
  • 日志收集
    • 记录全局事务ID(XID)到ELK或SkyWalking,支持快速定位问题。

7. 附录

7.1 示例代码仓库

  • Seata 官方示例
  • TransmittableThreadLocal 使用指南

7.2 相关工具

  • Seata Dashboard:可视化监控全局事务状态。
  • Prometheus + Grafana:监控TC集群性能指标。

版本记录

  • v1.0(2023-10-01):初版发布,涵盖XID传递、TC设计、失效场景解决方案。
  • v1.1(2023-10-05):补充异步任务配置示例与性能优化建议。

评审人:技术委员会
批准人:CTO


:本方案书需结合具体业务场景调整,建议在预生产环境充分验证。

http://www.xdnf.cn/news/3365.html

相关文章:

  • 图数据库榜单网站
  • 算法每日一题 | 入门-顺序结构-字母转换
  • X²+1素数问题
  • DirectX12(D3D12)基础教程七 深度模板视图\剔除\谓词
  • 【数据结构与算法】跳表实现详解
  • Windows结合WSL之ext4.vhdx不断增大问题
  • 第九节:文件操作
  • C++漫游指南——字符串篇与内存分配篇
  • ganesha-DBUS
  • 人形机器人的 “灵动密码”:动作捕捉与 AI 如何为其注入活力
  • BOSS的收入 - 华为OD机试(A卷,Java题解)
  • React-Native Android 多行被截断
  • Ubuntu 22.04 的 ROS 2 和 Carla 设置指南(其一)
  • Multicore-TSNE
  • 如何用GPU Instancing来优化树木草石重复模型
  • Kubernetes 配置中的 Selector 详解
  • GPU集群搭建步骤
  • 基础术语说明
  • 前端项目问题:TypeError: Failed to fetch dynamically imported module
  • 数据结构---【二叉搜索树】
  • Canvas基础篇:图形绘制
  • 工业质检领域相关近期顶会论文汇总CVPR2025
  • SALOME源码分析: SMESH模块
  • 2025-04-30 AIGC-如何做短片视频
  • 科学数据可视化工具库visIt安装和使用
  • 阿里云短信接入实现示例
  • IsaacLab最新2025教程(7)-创建Interactive Scene
  • Socket-UDP
  • Day.js一个2k轻量级的时间日期处理库
  • Modbus转PROFIBUS网关:电动机保护新突破!