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

分布式事务解决方案TCC实战

分布式事务解决方案TCC实战一、分布式事务概述在分布式系统中事务跨越多个服务或数据库传统的ACID事务无法直接适用需要采用分布式事务解决方案。1.1 分布式事务挑战挑战说明网络延迟跨服务调用存在网络延迟和超时数据一致性多个数据源需要保持一致故障恢复部分失败时需要回滚或补偿性能影响分布式锁和协调开销1.2 常见解决方案方案特点适用场景2PC强一致阻塞式数据一致性要求极高TCC最终一致非阻塞高并发场景Saga事件驱动长事务业务流程编排消息队列最终一致异步解耦场景二、TCC原理TCCTry-Confirm-Cancel是一种基于业务层面的分布式事务解决方案。2.1 TCC三阶段┌─────────────────────────────────────────────────────────────┐ │ 事务协调器 │ └─────────────────────────────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Try阶段 │ │ Confirm阶段 │ │ Cancel阶段 │ │ (预留资源) │ │ (确认提交) │ │ (取消释放) │ └─────────────────┘ └─────────────────┘ └─────────────────┘2.2 TCC状态机public enum TccStatus { TRYING(尝试中), CONFIRMING(确认中), CANCELING(取消中), SUCCESS(成功), FAILED(失败); }三、TCC实现3.1 TCC接口定义public interface TccTransaction { TccMethod(confirmMethod confirm, cancelMethod cancel) void tryExecute(TccContext context); void confirm(TccContext context); void cancel(TccContext context); }3.2 订单服务TCC实现Service public class OrderTccService implements TccTransaction { Autowired private OrderRepository orderRepository; Override public void tryExecute(TccContext context) { Order order Order.builder() .userId(context.getUserId()) .amount(context.getAmount()) .status(PENDING) .build(); orderRepository.save(order); context.setOrderId(order.getId()); context.setStatus(TccStatus.TRYING.name()); } Override public void confirm(TccContext context) { Order order orderRepository.findById(context.getOrderId()).orElse(null); if (order ! null PENDING.equals(order.getStatus())) { order.setStatus(SUCCESS); orderRepository.save(order); } context.setStatus(TccStatus.SUCCESS.name()); } Override public void cancel(TccContext context) { Order order orderRepository.findById(context.getOrderId()).orElse(null); if (order ! null PENDING.equals(order.getStatus())) { order.setStatus(CANCELLED); orderRepository.save(order); } context.setStatus(TccStatus.FAILED.name()); } }3.3 账户服务TCC实现Service public class AccountTccService implements TccTransaction { Autowired private AccountRepository accountRepository; Override public void tryExecute(TccContext context) { Account account accountRepository.findByUserId(context.getUserId()); if (account.getBalance() context.getAmount()) { throw new InsufficientBalanceException(余额不足); } account.setFreezeAmount(account.getFreezeAmount() context.getAmount()); account.setBalance(account.getBalance() - context.getAmount()); accountRepository.save(account); context.setStatus(TccStatus.TRYING.name()); } Override public void confirm(TccContext context) { Account account accountRepository.findByUserId(context.getUserId()); account.setFreezeAmount(account.getFreezeAmount() - context.getAmount()); accountRepository.save(account); context.setStatus(TccStatus.SUCCESS.name()); } Override public void cancel(TccContext context) { Account account accountRepository.findByUserId(context.getUserId()); account.setBalance(account.getBalance() context.getAmount()); account.setFreezeAmount(account.getFreezeAmount() - context.getAmount()); accountRepository.save(account); context.setStatus(TccStatus.FAILED.name()); } }四、事务协调器4.1 协调器设计Service public class TccCoordinator { Autowired private TransactionRepository transactionRepository; Autowired private ApplicationContext applicationContext; Transactional public String startTransaction(ListTccParticipant participants) { String transactionId UUID.randomUUID().toString(); Transaction transaction Transaction.builder() .transactionId(transactionId) .status(TccStatus.TRYING.name()) .participants(JsonUtil.toJson(participants)) .build(); transactionRepository.save(transaction); return transactionId; } public void commit(String transactionId) { Transaction transaction transactionRepository.findById(transactionId).orElse(null); if (transaction null) { return; } ListTccParticipant participants JsonUtil.fromJson( transaction.getParticipants(), new TypeReferenceListTccParticipant() {} ); for (TccParticipant participant : participants) { try { TccTransaction service applicationContext.getBean( participant.getServiceName(), TccTransaction.class ); TccContext context new TccContext(); context.setTransactionId(transactionId); context.setParams(participant.getParams()); service.confirm(context); } catch (Exception e) { rollback(transactionId); throw new TransactionCommitException(提交失败, e); } } transaction.setStatus(TccStatus.SUCCESS.name()); transactionRepository.save(transaction); } public void rollback(String transactionId) { Transaction transaction transactionRepository.findById(transactionId).orElse(null); if (transaction null) { return; } ListTccParticipant participants JsonUtil.fromJson( transaction.getParticipants(), new TypeReferenceListTccParticipant() {} ); for (TccParticipant participant : participants) { try { TccTransaction service applicationContext.getBean( participant.getServiceName(), TccTransaction.class ); TccContext context new TccContext(); context.setTransactionId(transactionId); context.setParams(participant.getParams()); service.cancel(context); } catch (Exception e) { // 记录日志后续人工处理 log.error(回滚失败: {}, e.getMessage()); } } transaction.setStatus(TccStatus.FAILED.name()); transactionRepository.save(transaction); } }4.2 TCC上下文public class TccContext { private String transactionId; private String status; private MapString, Object params new HashMap(); public void setParam(String key, Object value) { params.put(key, value); } public T T getParam(String key, ClassT clazz) { return clazz.cast(params.get(key)); } // getters and setters }五、异常处理与重试5.1 幂等性保证public class IdempotentUtil { private static final String PREFIX tcc:idempotent:; Autowired private StringRedisTemplate redisTemplate; public boolean checkAndLock(String key, long expireSeconds) { Boolean result redisTemplate.opsForValue().setIfAbsent( PREFIX key, locked, expireSeconds, TimeUnit.SECONDS ); return Boolean.TRUE.equals(result); } public void release(String key) { redisTemplate.delete(PREFIX key); } }5.2 重试机制Configuration public class RetryConfig { Bean public RetryTemplate retryTemplate() { RetryTemplate retryTemplate new RetryTemplate(); FixedBackOffPolicy backOffPolicy new FixedBackOffPolicy(); backOffPolicy.setBackOffPeriod(1000); retryTemplate.setBackOffPolicy(backOffPolicy); SimpleRetryPolicy retryPolicy new SimpleRetryPolicy(); retryPolicy.setMaxAttempts(3); retryTemplate.setRetryPolicy(retryPolicy); return retryTemplate; } }5.3 补偿任务Component public class CompensationTask { Autowired private TransactionRepository transactionRepository; Autowired private TccCoordinator coordinator; Scheduled(fixedDelay 60000) public void processPendingTransactions() { ListTransaction pendingTransactions transactionRepository.findByStatus( TccStatus.TRYING.name() ); for (Transaction transaction : pendingTransactions) { if (isTimeout(transaction.getCreateTime())) { coordinator.rollback(transaction.getTransactionId()); } } } private boolean isTimeout(Date createTime) { long diff System.currentTimeMillis() - createTime.getTime(); return diff 5 * 60 * 1000; // 5分钟超时 } }六、Seata TCC模式6.1 引入依赖dependency groupIdio.seata/groupId artifactIdseata-spring-boot-starter/artifactId version1.6.1/version /dependency6.2 配置文件seata: enabled: true application-id: order-service tx-service-group: my_tx_group config: type: nacos nacos: server-addr: localhost:8848 group: SEATA_GROUP namespace: registry: type: nacos nacos: server-addr: localhost:8848 group: SEATA_GROUP6.3 Seata TCC实现Service public class OrderTccServiceImpl { LocalTCC public void prepare(BusinessActionContext context, OrderDTO orderDTO) { Order order new Order(); order.setOrderId(orderDTO.getOrderId()); order.setStatus(PREPARE); orderRepository.save(order); context.setActionContext(orderId, orderDTO.getOrderId()); } public void commit(BusinessActionContext context) { String orderId context.getActionContext(orderId); Order order orderRepository.findByOrderId(orderId); order.setStatus(COMMITTED); orderRepository.save(order); } public void rollback(BusinessActionContext context) { String orderId context.getActionContext(orderId); Order order orderRepository.findByOrderId(orderId); order.setStatus(ROLLED_BACK); orderRepository.save(order); } }七、最佳实践7.1 设计原则幂等性Confirm和Cancel操作必须是幂等的可补偿性Cancel操作必须能正确回滚Try阶段的修改资源隔离Try阶段应锁定资源防止并发问题超时机制设置合理的超时时间自动触发Cancel7.2 注意事项事项说明网络分区考虑网络分区情况下的一致性保障数据库事务Try阶段应使用数据库事务保证原子性日志记录记录详细的事务日志便于排查问题监控告警监控事务成功率、失败率、超时率7.3 性能优化// 使用批量操作减少数据库访问 Transactional public void batchConfirm(ListString transactionIds) { ListTransaction transactions transactionRepository.findAllById(transactionIds); for (Transaction transaction : transactions) { // 批量更新状态 transaction.setStatus(TccStatus.SUCCESS.name()); } transactionRepository.saveAll(transactions); }八、总结TCC是一种灵活的分布式事务解决方案适用于高并发场景。通过合理设计Try、Confirm、Cancel三个阶段可以在保证最终一致性的同时获得较好的性能表现。关键要点TCC是业务层面的分布式事务解决方案需要保证Confirm和Cancel的幂等性需要实现超时和重试机制可以借助Seata等框架简化实现在实际应用中应根据业务场景选择合适的分布式事务方案平衡一致性、性能和复杂度。

相关文章:

分布式事务解决方案TCC实战

分布式事务解决方案TCC实战 一、分布式事务概述 在分布式系统中,事务跨越多个服务或数据库,传统的ACID事务无法直接适用,需要采用分布式事务解决方案。 1.1 分布式事务挑战 挑战说明网络延迟跨服务调用存在网络延迟和超时数据一致性多个数据源…...

CANN/catlass精度分析基础

精度分析基础 【免费下载链接】catlass 本项目是CANN的算子模板库,提供NPU上高性能矩阵乘及其相关融合类算子模板样例。 项目地址: https://gitcode.com/cann/catlass 写在前面 该文档主要说明CATLASS样例开发中精度分析的基础知识,包括样例精度…...

一套代码适配四种屏幕——StyleConfiguration 键盘多设备适配方案

文章目录问题在哪?StyleConfiguration 的设计思路KeyStyle 接口定义StyleConfiguration.getInputStyle 完整逻辑资源文件命名规范组件如何使用 StyleConfiguration屏幕旋转适配完整流程这种设计模式的通用价值踩坑记录写在最后搞输入法开发最头疼的事情之一就是屏幕…...

深入理解ops-tensor架构:模块化算子库的设计哲学与实现

深入理解ops-tensor架构:模块化算子库的设计哲学与实现 【免费下载链接】ops-tensor ops-tensor 是 CANN (Compute Architecture for Neural Networks)算子库中提供张量类计算的基础算子库,采用模块化设计,支持灵活的算…...

CANN/cann-learning-hub:Swan LLM 大模型实战课程

【免费下载链接】cann-learning-hub CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。 项目地址: https://gitcode.com/cann/cann-learning-hub SwanLab x CANN 社区合作课程 Swa…...

aFileChooser架构设计分析:Fragment、Loader和Intent的最佳实践

aFileChooser架构设计分析:Fragment、Loader和Intent的最佳实践 【免费下载链接】aFileChooser [DEPRECATED] Android library that provides a file explorer to let users select files on external storage. 项目地址: https://gitcode.com/gh_mirrors/af/aFil…...

Kubernetes 监控与可观测性深度解析:Prometheus + Grafana + Loki

Kubernetes 监控与可观测性深度解析:Prometheus Grafana Loki 引言 在云原生环境中,监控与可观测性是保障系统稳定运行的关键。Kubernetes 生态提供了丰富的监控工具,其中 Prometheus、Grafana 和 Loki 组成了完整的可观测性栈。本文将深…...

CANN/hcomm集群信息初始化API

HcclCommInitClusterInfo 【免费下载链接】hcomm HCOMM(Huawei Communication)是HCCL的通信基础库,提供通信域以及通信资源的管理能力。 项目地址: https://gitcode.com/cann/hcomm 产品支持情况 Ascend 950PR/Ascend 950DT&#xff1…...

大模型应用开发指南:从入门到实践,收藏这份从Demo到生产落地的完整攻略

本文分享了AI应用开发中从Demo到生产落地的完整实践,涵盖技术选型、架构设计、核心算法优化及部署经验。通过LangGraph、RAGFlow和Langfuse等工具,解决上下文超限、Prompt管理混乱等问题,最终实现准确率提升25%的工业级AI系统。适合程序员和小…...

Kafka-UI:3分钟快速上手,轻松管理你的Apache Kafka集群

Kafka-UI:3分钟快速上手,轻松管理你的Apache Kafka集群 【免费下载链接】kafka-ui Open-Source Web UI for managing Apache Kafka clusters 项目地址: https://gitcode.com/gh_mirrors/kaf/kafka-ui 你是否曾经为管理Apache Kafka集群而头疼&…...

Kilim Actor模型实践:构建高并发消息传递系统的终极指南 [特殊字符]

Kilim Actor模型实践:构建高并发消息传递系统的终极指南 🚀 【免费下载链接】kilim Lightweight threads for Java, with message passing, nio, http and scheduling support. 项目地址: https://gitcode.com/gh_mirrors/ki/kilim Kilim是一个强…...

C++二叉树构建、深拷贝与可视化输出实战解析

1. 项目概述:从零构建与复制二叉树在C的日常开发中,尤其是涉及到算法、数据结构或者需要处理层次化数据的场景,二叉树是一个绕不开的基础结构。最近我在重构一个旧的项目模块,其中核心需求就是需要动态生成一个数据结构&#xff0…...

HC32F4A0外设引脚自由配置全攻略:如何像STM32重映射一样灵活规划你的原理图?

HC32F4A0外设引脚自由配置全攻略:如何像STM32重映射一样灵活规划你的原理图? 在嵌入式硬件设计中,引脚规划往往是决定项目成败的关键第一步。传统MCU如STM32通过固定功能引脚和有限的重映射功能,给工程师带来诸多限制。而华大半导…...

Purple Pi OH开发板Android 11系统ROOT权限获取与Magisk实战指南

1. 项目概述:为什么我们需要对Purple Pi OH进行ROOT?拿到一块Purple Pi OH开发板,刷上Android 11系统,对于开发者或极客玩家来说,最常遇到的第一个“痒点”可能就是权限不足。系统默认运行在“用户模式”下&#xff0c…...

从飞思卡尔智能车竞赛视频拆解嵌入式系统设计:感知、控制与工程实践

1. 项目概述:从一场竞赛视频看智能车设计的核心逻辑最近在整理资料时,翻到了当年飞思卡尔智能车竞赛(现为全国大学生智能汽车竞赛)中湖南大学参赛队伍的一些视频资料。这些视频,无论是官方发布的比赛实录,还…...

Windows上运行安卓应用:APK安装器完整指南

Windows上运行安卓应用:APK安装器完整指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 想在Windows电脑上直接运行安卓应用,却不想安装笨重的…...

5分钟快速上手SignTools:自托管iOS应用签名平台完整教程

5分钟快速上手SignTools:自托管iOS应用签名平台完整教程 【免费下载链接】SignTools ✒ A free, self-hosted platform to sideload iOS apps without a computer 项目地址: https://gitcode.com/gh_mirrors/si/SignTools 想要在iOS设备上自由安装第三方应用…...

开发智能客服系统时利用 Taotoken 实现模型降级与容灾路由的策略

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 开发智能客服系统时利用 Taotoken 实现模型降级与容灾路由的策略 在构建面向真实用户的智能客服系统时,服务的连续性与…...

CodeGPT高级代理系统:10个实用工具助你高效编程的完整指南

CodeGPT高级代理系统:10个实用工具助你高效编程的完整指南 【免费下载链接】CodeGPT The leading open-source AI copilot for JetBrains. Connect to any model in any environment, and customize your coding experience in any way you like. 项目地址: https…...

一键切换语境+保留术语一致性+上下文感知翻译,Perplexity翻译查询功能的3大颠覆性能力,现在不用就落后了

更多请点击: https://codechina.net 第一章:Perplexity翻译查询功能的全景概览 Perplexity 的翻译查询功能并非传统意义上的“文本翻译器”,而是一种融合语义理解、上下文感知与多语言知识检索的智能问答增强机制。它允许用户以任意自然语言…...

从防御者视角看Fastjson 1.2.24漏洞:如何用Docker+vulhub快速搭建靶场并验证修复方案

防御视角下的Fastjson 1.2.24漏洞实战:Docker靶场搭建与修复方案验证 在当今的软件开发中,JSON处理库的安全性问题日益凸显。作为Java生态中最流行的JSON库之一,Fastjson因其高性能而广受欢迎,但同时也因其历史漏洞频发而备受关注…...

CANN/asnumpy-docs 架构设计

Architecture 【免费下载链接】asnumpy-docs 项目地址: https://gitcode.com/cann/asnumpy-docs This document describes the internal architecture of AsNumpy, including the three-layer design, the core NPUArray data structure, the API module layout, and t…...

ArcGIS Pro 3.x 批量处理遥感栅格:用Python脚本实现自动化转点、计算与导出(附完整代码)

ArcGIS Pro 3.x 遥感栅格自动化处理实战:从数据清洗到生产级流水线构建 遥感数据分析师常常需要处理TB级的时序栅格数据,比如月度NDVI指数、地表温度或降水分布。传统手动操作不仅效率低下,还容易因人为失误导致数据不一致。本文将分享如何基…...

Onyx Core API完全手册:RESTful接口详解与实战案例

Onyx Core API完全手册:RESTful接口详解与实战案例 【免费下载链接】Onyx Onyx 项目地址: https://gitcode.com/gh_mirrors/ony/Onyx Onyx Core是一个强大的企业级区块链平台,提供完整的RESTful API接口,让开发者能够轻松构建和管理区…...

昇腾C解交织API文档

DeInterleave 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.c…...

Windows缩略图加载太慢?这款智能预加载工具让文件浏览快如闪电

Windows缩略图加载太慢?这款智能预加载工具让文件浏览快如闪电 【免费下载链接】WinThumbsPreloader-V2 WinThumbsPreloader is a powerful open source tool for quickly preloading thumbnails in Windows Explorer. 项目地址: https://gitcode.com/gh_mirrors/…...

ncmdump终极指南:5分钟解锁网易云音乐NCM加密文件

ncmdump终极指南:5分钟解锁网易云音乐NCM加密文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾在网易云音乐下载了心爱的歌曲,却发现只能在特定客户端播放?当你想在车载音响、智能音箱…...

靠谱的远程手机控制软件 远程控制手机推荐用无界趣连2.0

靠谱的远程手机控制软件,能帮我们打破设备空间限制,日常办公、远程协助或游戏串流都能高效搞定。在众多远程手机控制软件里,无界趣连2.0凭借扎实的性能与无套路的体验,成为不少用户的首选,不管是新手还是老手&#xff…...

电力系统时序一致性保障:elec-ops-prediction的长时序稳定性约束实现

电力系统时序一致性保障:elec-ops-prediction的长时序稳定性约束实现 【免费下载链接】elec-ops-prediction elec-ops-prediction 是 CANN 社区 Electrical Engineering SIG(电力行业兴趣小组)旗下的电力负荷预测算子库, 聚焦于电…...

3分钟彻底解决Cursor试用限制:设备标识重置技术深度解析

3分钟彻底解决Cursor试用限制:设备标识重置技术深度解析 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Your request has been blocked as our system has detected suspicious activity / Youve reached your trial request limit…...