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

Seata模式

Seata分布式事务模式终极指南:从原理到实践的全方位解析

一、Seata深度剖析

1.1 Seata架构全景

Seata采用三层架构设计,各组件协同工作:

TC (Transaction Coordinator)

  • 全局事务大脑,负责事务生命周期管理

  • 核心功能:

    • 全局事务的发起与终止

    • 分支事务的注册与状态管理

    • 全局锁的分配与释放

  • 部署方式:独立服务,支持集群部署

TM (Transaction Manager)

  • 事务发起方,定义事务边界

  • 关键行为:

    • 通过@GlobalTransactional注解声明全局事务

    • 决定全局事务的提交或回滚

    • 与TC保持心跳检测

RM (Resource Manager)

  • 资源管理者,处理分支事务

  • 核心职责:

    • 向TC注册分支事务

    • 报告分支事务状态

    • 执行TC的提交/回滚指令

    • 管理本地资源(如数据库连接)

1.2 事务上下文传播机制

Seata通过XID(全局事务ID)实现跨服务调用的事务上下文传播:

  1. XID生成:TM发起全局事务时,TC生成唯一XID

  2. 上下文注入

    java

    复制

    下载

    // Feign拦截器示例
    public class SeataFeignInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {String xid = RootContext.getXID();if (StringUtils.isNotBlank(xid)) {template.header(RootContext.KEY_XID, xid);}}
    }
  3. 跨服务传递:通过HTTP Header/RPC上下文传递XID

  4. 分支关联:RM通过XID将分支事务与全局事务关联

二、AT模式技术内幕

2.1 完整执行流程

阶段一:业务执行

  1. SQL解析:使用Druid解析SQL,提取表、条件等信息

  2. 前镜像生成

    SELECT * FROM product WHERE id = 1 FOR UPDATE
  3. 业务SQL执行

    UPDATE product SET stock = stock - 1 WHERE id = 1
  4. 后镜像生成

    SELECT * FROM product WHERE id = 1
  5. undo_log记录

    {"branchId": 641253,"xid": "192.168.1.1:8091:641253","rollbackInfo": {"beforeImage": {"rows": [{"id":1,"stock":10}]},"afterImage": {"rows": [{"id":1,"stock":9}]}}
    }

阶段二:全局提交

  1. TC异步通知各RM删除undo_log

  2. 释放全局锁

阶段二:全局回滚

  1. 校验脏写:比较当前数据与afterImage

  2. 生成补偿SQL:

    UPDATE product SET stock = 10 WHERE id = 1
  3. 提交补偿事务

  4. 删除undo_log

2.2 关键技术实现

全局锁设计

  • 存储结构:global_table表存储锁记录

  • 获取流程:

    1. 检查是否存在冲突锁

    2. 插入锁记录(行锁)

    3. 设置锁超时(默认60s)

undo_log优化

  • 压缩存储:对大字段进行压缩

  • 异步清理:后台线程定期清理已提交的事务日志

  • 分表设计:按xid哈希分表存储

三、TCC模式深度实践

3.1 完整实现案例

账户服务TCC接口

public interface AccountTccService {@TwoPhaseBusinessAction(name = "freezeAmount", commitMethod = "confirm", rollbackMethod = "cancel")boolean freeze(@BusinessActionContextParameter(paramName = "userId") Long userId,@BusinessActionContextParameter(paramName = "amount") BigDecimal amount);boolean confirm(BusinessActionContext context);boolean cancel(BusinessActionContext context);
}

Try阶段实现

@Override
public boolean freeze(Long userId, BigDecimal amount) {// 检查账户状态Account account = accountDao.selectById(userId);if (account.getStatus() != AccountStatus.ACTIVE) {throw new IllegalStateException("账户非活跃状态");}// 检查余额是否充足if (account.getAvailable().compareTo(amount) < 0) {throw new IllegalArgumentException("余额不足");}// 冻结金额accountDao.freezeAmount(userId, amount);// 记录冻结流水FreezeRecord record = new FreezeRecord();record.setXid(RootContext.getXID());record.setUserId(userId);record.setAmount(amount);freezeRecordDao.insert(record);return true;
}

Cancel阶段异常处理

@Override
public boolean cancel(BusinessActionContext context) {// 处理空回滚if (!freezeRecordDao.exists(context.getXid())) {log.warn("收到未执行try的空回滚,xid={}", context.getXid());return true;}// 幂等控制if (freezeRecordDao.isCanceled(context.getXid())) {return true;}// 执行解冻Long userId = context.getActionContext("userId");BigDecimal amount = context.getActionContext("amount");try {accountDao.unfreezeAmount(userId, amount);freezeRecordDao.markCanceled(context.getXid());} catch (Exception e) {// 重试机制throw new SeataTccException("解冻失败,需要重试", e);}return true;
}

3.2 TCC模式设计规范

  1. 服务设计原则

    • 预留资源要充足

    • Confirm必须幂等

    • Cancel需要处理空回滚

  2. 事务日志设计

    CREATE TABLE tcc_action_record (id BIGINT PRIMARY KEY,xid VARCHAR(128) NOT NULL,action_name VARCHAR(64) NOT NULL,status TINYINT NOT NULL,  -- 1:TRY,2:CONFIRM,3:CANCELargs_json TEXT,create_time DATETIME,update_time DATETIME,UNIQUE KEY uk_xid_action (xid, action_name)
    );
  3. 超时处理机制

    • 设置合理的事务超时时间

    • 实现定时任务扫描悬挂事务

    • 提供人工干预接口

四、SAGA模式企业级实现

4.1 状态机设计

订单流程状态机

StateMachineBuilder<OrderState, OrderEvent> builder = StateMachineBuilderFactory.create();builder.externalTransition().from(OrderState.INIT).to(OrderState.PAYING).on(OrderEvent.PAY).when(checkCondition()).perform(doAction());builder.externalTransition().from(OrderState.PAYING).to(OrderState.PAID).on(OrderEvent.PAY_SUCCESS).when(checkCondition()).perform(doAction());builder.externalTransition().from(OrderState.PAYING).to(OrderState.FAILED).on(OrderEvent.PAY_FAILED).when(checkCondition()).perform(compensationAction());

4.2 补偿策略实现

并行补偿策略

public class ParallelCompensationStrategy implements CompensationStrategy {@Overridepublic void compensate(List<Transaction> transactions) {transactions.parallelStream().forEach(tx -> {try {tx.compensate();} catch (Exception e) {log.error("补偿执行失败", e);// 记录失败,后续重试compensationFailureRecorder.record(tx);}});}
}

顺序补偿策略

public class SequentialCompensationStrategy implements CompensationStrategy {@Overridepublic void compensate(List<Transaction> transactions) {for (Transaction tx : transactions) {int retry = 0;while (retry < MAX_RETRY) {try {tx.compensate();break;} catch (Exception e) {retry++;if (retry == MAX_RETRY) {throw new CompensationException("补偿最终失败");}sleep(1000 * retry);}}}}
}

五、XA模式生产实践

5.1 深度集成方案

数据源代理配置

@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource")public DruidDataSource druidDataSource() {return new DruidDataSource();}@Primary@Beanpublic DataSource dataSource(DruidDataSource druidDataSource) {return new DataSourceProxyXA(druidDataSource);}
}

XA事务日志表

CREATE TABLE xa_log (xid VARCHAR(128) NOT NULL,branch_id VARCHAR(128) NOT NULL,status TINYINT NOT NULL,gmt_create DATETIME NOT NULL,gmt_modified DATETIME NOT NULL,PRIMARY KEY (xid, branch_id)
);

5.2 性能优化方案

  1. 连接池优化

    spring:datasource:druid:initial-size: 5max-active: 20min-idle: 5max-wait: 60000validation-query: SELECT 1test-while-idle: truetest-on-borrow: false
  2. 批量操作优化

    @GlobalTransactional
    public void batchImport(List<Product> products) {jdbcTemplate.batchUpdate("INSERT INTO product(name,price) VALUES(?,?)",products,100,  // 批处理大小(ps, product) -> {ps.setString(1, product.getName());ps.setBigDecimal(2, product.getPrice());});
    }

六、混合模式实战

6.1 AT与TCC混用方案

订单创建流程

@GlobalTransactional
public void createOrder(OrderDTO orderDTO) {// AT模式操作:订单记录创建orderMapper.insert(orderDTO);// TCC模式调用:库存扣减inventoryTccService.reduceStock(orderDTO.getProductId(), orderDTO.getQuantity());// AT模式操作:日志记录orderLogService.recordCreateLog(orderDTO);
}

6.2 SAGA与TCC混用方案

跨境支付流程

@SagaStart
public void crossBorderPayment(PaymentRequest request) {// TCC模式:冻结本地账户资金accountTccService.freeze(request.getUserId(),request.getAmount());// 调用外汇服务(AT模式)exchangeService.convert(request.getFromCurrency(),request.getToCurrency(),request.getAmount());// 调用境外支付(SAGA模式)foreignPaymentService.pay(request.getToAccount(),request.getConvertedAmount());
}

七、性能调优指南

7.1 参数优化配置

server端配置

properties

# 事务日志存储模式(推荐DB)
store.mode=db# 全局事务超时时间(毫秒)
server.max.commit.retry.timeout=60000
server.max.rollback.retry.timeout=60000# 全局锁竞争检测间隔
server.lock.retry.internal=10
server.lock.retry.times=30

client端配置

properties

# RM报告重试次数
client.rm.report.retry.count=5# 全局锁获取超时时间
client.lock.retry.timeout=30000# 异步提交缓冲队列大小
client.async.commit.buffer.limit=10000

7.2 监控体系搭建

Prometheus监控指标

metrics:enabled: trueregistry-type: compactexporter-list: prometheusexporter-prometheus-port: 9898

关键监控指标

  1. 全局事务成功率

  2. 各模式事务平均耗时

  3. 全局锁竞争次数

  4. 二阶段提交/回滚延迟

  5. 资源占用情况

八、异常处理大全

8.1 常见问题解决方案

全局锁冲突

  1. 优化方案:

    • 减小事务粒度

    • 添加重试机制

    @Retryable(maxAttempts=3, backoff=@Backoff(delay=100))
    public void doBusiness() {// 业务逻辑
    }
  2. 应急方案:

    • 临时提高锁超时时间

    • 人工干预解除锁

事务悬挂

  1. 预防措施:

    • 完善空回滚处理

    • 添加事务状态校验

  2. 检测方案:

    SELECT * FROM undo_log 
    WHERE gmt_create < DATE_SUB(NOW(), INTERVAL 1 HOUR)
    AND status = 'PREPARED';

8.2 灾备方案设计

TC集群故障处理

  1. 快速恢复方案:

    • 备用TC集群切换

    • 事务日志恢复

  2. 业务降级方案:

    • 本地事务保障核心流程

    • 消息队列补偿最终一致性

九、未来演进方向

  1. 云原生支持

    • 容器化部署优化

    • Service Mesh集成

    • K8s Operator开发

  2. 多语言生态

    • Go语言实现

    • Python客户端支持

    • Node.js适配

  3. 新特性规划

    • 分布式事务链追踪

    • 智能模式推荐

    • 自动熔断降级

http://www.lqws.cn/news/465913.html

相关文章:

  • Spring AOP全面详讲
  • 从 Elasticsearch 集群中移除一个节点
  • `customRef` 在实战中的使用:防抖、计算属性缓存和异步数据获取
  • 腾讯云IM即时通讯:开启实时通信新时代
  • nuxt3 + vue3 分片上传组件全解析(支持大文件+断点续传)
  • RabbitMQ 的工作流程
  • 【unitrix】 3.6 类型级数转基础类型(from.rs)
  • springboot通过独立事务管理器实现资源隔离与精准控制​
  • HTTPS的加密方式介绍
  • MinIO社区版文件预览失效?一招解决
  • 【Fargo】mediasoup发送2:码率分配、传输基类设计及WebRtcTransport原理
  • React 组件通信
  • C++ 移动构造:提升性能的利器
  • docker执行yum报错Could not resolve host: mirrorlist.centos.org
  • Snapchat矩阵运营新策略:亚矩阵云手机打造高效社交网络
  • C++:动态链接库的编写,__declspec 用法详解
  • 7.3.2_2平衡二叉树的删除
  • 【RTP】基于mediasoup的RtpPacket的H.264打包、解包和demo 1:不含扩展
  • windows下docker虚拟文件大C盘迁移D盘
  • GPT-1 与 BERT 架构
  • TodoList 案例(Vue3): 使用Composition API
  • 基于CNN-LSTM融合模型的环卫车动态称重算法研究:从频率感知到精准质量估计
  • 深入浅出JavaScript 中的代理模式:用 Proxy 掌控对象的“行为开关”
  • Python 爬虫案例(不定期更新)
  • Occt几何内核快速入门
  • Duende Identity Server学习之一:认证服务器及一个Oidc/OAuth认证、用于Machine 2 Machine的客户端
  • 在Docker、KVM、K8S常见主要命令以及在Centos7.9中部署的关键步骤学习备存
  • stm32移植freemodbus
  • C++ - vector 的使用
  • 【转】如何画好架构图:架构思维的三大底层逻辑