论分布式事务及其解决方案 原文

返回主题详情 背诵模式

原文文件:论分布式事务及其解决方案-线上商品交易与运营平台.md

# 论分布式事务及其解决方案

## 摘要

2024 年 3 月,我参与了某互联网公司线上商品交易与运营平台的建设工作。该平台围绕公司线上交易业务的统一运营需要,实现了商品交易、库存协同和经营分析等工作的集中支撑。在该项目中,我担任系统架构设计师,主要负责总体架构设计、关键技术选型、模块划分、接口规范制定和核心方案评审工作。本文以该系统为例,主要论述分布式事务及其解决方案在项目中的具体应用。结合本项目交易链路集中、订单状态变化频繁、库存和支付协作要求较高等特点,我们主要采用了事务消息、补偿事务和幂等控制等措施。实践证明,上述措施较好地保证了跨服务业务处理的最终一致性,提高了系统运行稳定性和异常恢复能力,保证了项目顺利上线运行。

## 正文

随着公司线上经营规模不断扩大,业务活动从单一的商品展示和订单处理,逐步延伸到活动运营、库存协同、售后服务和经营分析等多个环节,各项业务对信息系统连续、稳定支撑的要求也越来越高。该项目建设前,公司线上交易业务主要依靠原有单体系统和若干后台工具支撑,虽然能够满足早期业务需要,但随着活动数量、用户访问量和订单处理量持续增加,原系统在业务协同和运行效率方面逐渐难以适应发展要求。特别是在活动高峰期,交易请求集中到达,订单生成、支付确认、库存处理和状态查询等环节相互依赖,容易出现响应延迟和状态不一致的情况;运营人员也需要在多个后台之间反复核对活动配置和交易数据,影响了业务处理效率。为了提高线上交易处理效率,规范商品和订单管理流程,降低后续系统维护成本,公司决定建设统一的线上商品交易与运营平台。

本项目于 2024 年 3 月启动,历时 10 个月完成核心功能建设并上线运行,项目组共 21 人。系统采用前后端分离方式建设,服务端以 Java 技术体系为主,并结合网关、缓存、数据库、消息队列和定时任务等技术组件完成系统支撑。平台上线后,用户侧交易流程由统一入口承载,运营人员也可以通过后台集中维护商品活动信息,并统一监控交易和对账情况。我在项目中担任系统架构设计师,主要负责总体架构设计、关键技术选型、模块划分、接口规范制定和核心方案评审,历时 4 个月完成主要架构设计工作。结合该平台订单、库存、支付和对账之间协作频繁的特点,我在架构设计中重点考虑了分布式事务处理问题。

在架构设计工作开始阶段,我认识到,分布式事务及其解决方案是进行分布式系统建设和交易链路设计时需要重点考虑的内容。分布式事务用于解决一次业务操作跨越多个服务或多个数据资源时的数据一致性问题,其核心是在一致性、可用性和系统性能之间进行合理权衡。常见的分布式事务解决方法包括两阶段提交、TCC、事务消息、补偿事务和最终一致性等。本项目主要采用了事务消息、补偿事务和幂等控制。其中,事务消息用于衔接本地事务和后续异步处理,保证关键状态能够可靠传递;补偿事务用于在外部接口延迟或部分环节失败时恢复业务状态;幂等控制用于避免重复请求和重复消息造成重复扣减或重复更新。以下正文将重点描述这些措施的实施过程和应用效果。

在订单创建和库存处理环节,我们采用事务消息来满足跨服务处理最终一致的要求。该平台在用户下单时需要同时完成订单生成、库存占用和后续通知等工作,如果把这些操作全部放在一个同步事务中,系统会长时间等待库存处理和外部接口结果,活动高峰期吞吐量明显下降;如果完全不做一致性控制,又可能出现订单已经生成但库存没有占用的情况。为解决这一问题,我组织项目组将订单创建作为本地事务的核心边界,在 MySQL 中保存订单及其初始状态,同时通过 RocketMQ 发送订单创建消息,通知库存和消息等模块继续处理。具体运行时,用户提交订单后,订单模块先保证订单记录可靠落库,再发布后续处理消息;库存模块收到消息后完成库存占用,并记录处理结果。以活动商品下单为例,即使库存处理短时间排队,订单记录和后续处理消息也能够保持对应关系。通过事务消息,系统在不长时间阻塞用户请求的前提下,使订单和库存处理达到最终一致。

在支付确认和订单状态流转方面,我们采用补偿事务来满足外部支付结果延迟和异常恢复的要求。线上支付过程需要依赖第三方支付平台,支付回调可能出现延迟、重复或短暂失败,如果订单状态只依赖一次同步回调,就可能出现用户已经支付成功而平台订单仍停留在待支付状态的问题。为解决这一问题,我们将支付流水和订单状态分开记录,并设计了定时补偿机制。具体做法是,支付模块接收到回调后先保存支付流水,再通知订单模块更新状态;对于长时间未收到回调或状态不一致的订单,由 xxl-job 定时扫描订单和支付流水,并根据支付平台查询结果执行补偿确认或关闭处理。以支付成功但订单状态未更新为例,补偿任务会根据支付流水重新推动订单状态变更,并记录补偿过程供客服查询。通过补偿事务,系统能够处理外部接口不稳定带来的状态不一致问题,提高了交易流程的可恢复性。

在重复提交和重复消费控制方面,我们采用幂等控制来满足交易结果唯一性的要求。线上交易场景中,用户可能因为网络延迟重复点击提交按钮,支付平台也可能重复推送回调,消息队列在异常重试时也可能重复投递同一类消息。如果没有幂等机制,就可能造成重复生成订单、重复扣减库存或重复发送通知等问题。为解决这一问题,我们在关键业务环节设置了业务唯一标识和处理状态判断。具体实现时,订单模块根据用户、商品和活动生成防重标识,库存模块根据订单号控制库存处理唯一性,支付模块根据支付流水号控制回调处理唯一性;Redis 用于快速拦截短时间重复请求,MySQL 唯一约束作为最终校验手段。以支付回调为例,同一支付流水只允许推动一次订单状态变更,后续重复回调只记录日志而不重复处理。通过幂等控制,系统在高并发、网络重试和消息重复投递情况下仍能保证交易结果正确,降低了分布式事务处理的风险。

整个项目于 2025 年 1 月完成核心功能上线,并在公司主要业务线推广使用。系统上线后,先后支撑了多次业务活动和交易高峰,整体运行情况较为平稳,核心业务流程能够正常开展,运营和客服人员也能够通过统一平台完成日常处理工作。上线运行期间,系统未发生重大生产事故,少量异常数据能够通过补偿任务和人工复核及时处理,维护工作量处于可控范围。经过一段时间运行,该平台基本满足了公司线上交易和运营管理的需要,提高了业务处理效率,减少了运营人员的重复操作,并得到了业务部门的认可。实践证明,事务消息、补偿事务和幂等控制对于本项目中跨服务数据一致性和异常恢复起到了较好的支撑作用。

在总结项目经验的同时,我也看到本项目仍然存在一些不足。第一,活动高峰期部分热门商品访问较为集中,个别页面和查询接口在峰值情况下响应时间仍有波动;第二,分布式事务处理引入了异步消息、补偿任务和幂等判断,对问题定位和运维监控提出了更高要求,个别异常订单仍需要人工复核。针对第一类问题,后续我们计划继续优化热点数据缓存、查询索引和资源扩容策略;针对第二类问题,我们将进一步完善事务链路监控、补偿任务告警和异常订单处理规则,减少人工核对工作。通过本项目实践,我认识到,分布式事务解决方案不能简单追求强一致,也不能完全忽略业务结果的正确性,而应结合具体业务场景在性能、可用性和一致性之间进行权衡。只有把事务边界、补偿机制和幂等控制设计清楚,才能使系统在复杂交易场景下长期稳定地支撑业务发展。